Sphinx 8.1.2__py3-none-any.whl → 8.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of Sphinx might be problematic. Click here for more details.

Files changed (328) hide show
  1. sphinx/__init__.py +8 -4
  2. sphinx/__main__.py +2 -0
  3. sphinx/_cli/__init__.py +2 -5
  4. sphinx/_cli/util/colour.py +34 -11
  5. sphinx/_cli/util/errors.py +128 -61
  6. sphinx/addnodes.py +51 -35
  7. sphinx/application.py +362 -230
  8. sphinx/builders/__init__.py +87 -64
  9. sphinx/builders/_epub_base.py +65 -56
  10. sphinx/builders/changes.py +17 -23
  11. sphinx/builders/dirhtml.py +8 -13
  12. sphinx/builders/epub3.py +70 -38
  13. sphinx/builders/gettext.py +93 -73
  14. sphinx/builders/html/__init__.py +240 -186
  15. sphinx/builders/html/_assets.py +9 -2
  16. sphinx/builders/html/_build_info.py +3 -0
  17. sphinx/builders/latex/__init__.py +64 -54
  18. sphinx/builders/latex/constants.py +14 -11
  19. sphinx/builders/latex/nodes.py +2 -0
  20. sphinx/builders/latex/theming.py +8 -9
  21. sphinx/builders/latex/transforms.py +7 -5
  22. sphinx/builders/linkcheck.py +193 -149
  23. sphinx/builders/manpage.py +17 -17
  24. sphinx/builders/singlehtml.py +28 -16
  25. sphinx/builders/texinfo.py +28 -21
  26. sphinx/builders/text.py +10 -15
  27. sphinx/builders/xml.py +10 -19
  28. sphinx/cmd/build.py +49 -119
  29. sphinx/cmd/make_mode.py +35 -31
  30. sphinx/cmd/quickstart.py +78 -62
  31. sphinx/config.py +265 -163
  32. sphinx/directives/__init__.py +51 -54
  33. sphinx/directives/admonitions.py +107 -0
  34. sphinx/directives/code.py +24 -19
  35. sphinx/directives/other.py +21 -42
  36. sphinx/directives/patches.py +28 -16
  37. sphinx/domains/__init__.py +54 -31
  38. sphinx/domains/_domains_container.py +22 -17
  39. sphinx/domains/_index.py +5 -8
  40. sphinx/domains/c/__init__.py +366 -245
  41. sphinx/domains/c/_ast.py +378 -256
  42. sphinx/domains/c/_ids.py +89 -31
  43. sphinx/domains/c/_parser.py +283 -214
  44. sphinx/domains/c/_symbol.py +269 -198
  45. sphinx/domains/changeset.py +39 -24
  46. sphinx/domains/citation.py +54 -24
  47. sphinx/domains/cpp/__init__.py +517 -362
  48. sphinx/domains/cpp/_ast.py +999 -682
  49. sphinx/domains/cpp/_ids.py +133 -65
  50. sphinx/domains/cpp/_parser.py +746 -588
  51. sphinx/domains/cpp/_symbol.py +692 -489
  52. sphinx/domains/index.py +10 -8
  53. sphinx/domains/javascript.py +152 -74
  54. sphinx/domains/math.py +50 -40
  55. sphinx/domains/python/__init__.py +402 -211
  56. sphinx/domains/python/_annotations.py +134 -61
  57. sphinx/domains/python/_object.py +155 -68
  58. sphinx/domains/rst.py +94 -49
  59. sphinx/domains/std/__init__.py +510 -249
  60. sphinx/environment/__init__.py +345 -61
  61. sphinx/environment/adapters/asset.py +7 -1
  62. sphinx/environment/adapters/indexentries.py +15 -20
  63. sphinx/environment/adapters/toctree.py +19 -9
  64. sphinx/environment/collectors/__init__.py +3 -1
  65. sphinx/environment/collectors/asset.py +18 -15
  66. sphinx/environment/collectors/dependencies.py +8 -10
  67. sphinx/environment/collectors/metadata.py +6 -4
  68. sphinx/environment/collectors/title.py +3 -1
  69. sphinx/environment/collectors/toctree.py +4 -4
  70. sphinx/errors.py +1 -3
  71. sphinx/events.py +4 -4
  72. sphinx/ext/apidoc/__init__.py +66 -0
  73. sphinx/ext/apidoc/__main__.py +9 -0
  74. sphinx/ext/apidoc/_cli.py +356 -0
  75. sphinx/ext/apidoc/_extension.py +262 -0
  76. sphinx/ext/apidoc/_generate.py +356 -0
  77. sphinx/ext/apidoc/_shared.py +99 -0
  78. sphinx/ext/autodoc/__init__.py +837 -483
  79. sphinx/ext/autodoc/directive.py +57 -21
  80. sphinx/ext/autodoc/importer.py +184 -67
  81. sphinx/ext/autodoc/mock.py +25 -10
  82. sphinx/ext/autodoc/preserve_defaults.py +17 -9
  83. sphinx/ext/autodoc/type_comment.py +56 -29
  84. sphinx/ext/autodoc/typehints.py +49 -26
  85. sphinx/ext/autosectionlabel.py +28 -11
  86. sphinx/ext/autosummary/__init__.py +281 -142
  87. sphinx/ext/autosummary/generate.py +121 -51
  88. sphinx/ext/coverage.py +152 -91
  89. sphinx/ext/doctest.py +169 -101
  90. sphinx/ext/duration.py +12 -6
  91. sphinx/ext/extlinks.py +33 -21
  92. sphinx/ext/githubpages.py +8 -8
  93. sphinx/ext/graphviz.py +175 -109
  94. sphinx/ext/ifconfig.py +11 -6
  95. sphinx/ext/imgconverter.py +48 -25
  96. sphinx/ext/imgmath.py +127 -97
  97. sphinx/ext/inheritance_diagram.py +177 -103
  98. sphinx/ext/intersphinx/__init__.py +22 -13
  99. sphinx/ext/intersphinx/__main__.py +3 -1
  100. sphinx/ext/intersphinx/_cli.py +18 -14
  101. sphinx/ext/intersphinx/_load.py +91 -82
  102. sphinx/ext/intersphinx/_resolve.py +108 -74
  103. sphinx/ext/intersphinx/_shared.py +2 -2
  104. sphinx/ext/linkcode.py +28 -12
  105. sphinx/ext/mathjax.py +60 -29
  106. sphinx/ext/napoleon/__init__.py +19 -7
  107. sphinx/ext/napoleon/docstring.py +229 -231
  108. sphinx/ext/todo.py +44 -49
  109. sphinx/ext/viewcode.py +105 -57
  110. sphinx/extension.py +3 -1
  111. sphinx/highlighting.py +13 -7
  112. sphinx/io.py +9 -13
  113. sphinx/jinja2glue.py +29 -26
  114. sphinx/locale/__init__.py +8 -9
  115. sphinx/locale/ar/LC_MESSAGES/sphinx.mo +0 -0
  116. sphinx/locale/ar/LC_MESSAGES/sphinx.po +2155 -2050
  117. sphinx/locale/bg/LC_MESSAGES/sphinx.mo +0 -0
  118. sphinx/locale/bg/LC_MESSAGES/sphinx.po +2045 -1940
  119. sphinx/locale/bn/LC_MESSAGES/sphinx.mo +0 -0
  120. sphinx/locale/bn/LC_MESSAGES/sphinx.po +2175 -2070
  121. sphinx/locale/ca/LC_MESSAGES/sphinx.js +3 -3
  122. sphinx/locale/ca/LC_MESSAGES/sphinx.mo +0 -0
  123. sphinx/locale/ca/LC_MESSAGES/sphinx.po +2690 -2585
  124. sphinx/locale/ca@valencia/LC_MESSAGES/sphinx.js +63 -0
  125. sphinx/locale/ca@valencia/LC_MESSAGES/sphinx.mo +0 -0
  126. sphinx/locale/ca@valencia/LC_MESSAGES/sphinx.po +4216 -0
  127. sphinx/locale/cak/LC_MESSAGES/sphinx.mo +0 -0
  128. sphinx/locale/cak/LC_MESSAGES/sphinx.po +2096 -1991
  129. sphinx/locale/cs/LC_MESSAGES/sphinx.mo +0 -0
  130. sphinx/locale/cs/LC_MESSAGES/sphinx.po +2248 -2143
  131. sphinx/locale/cy/LC_MESSAGES/sphinx.mo +0 -0
  132. sphinx/locale/cy/LC_MESSAGES/sphinx.po +2201 -2096
  133. sphinx/locale/da/LC_MESSAGES/sphinx.mo +0 -0
  134. sphinx/locale/da/LC_MESSAGES/sphinx.po +2282 -2177
  135. sphinx/locale/de/LC_MESSAGES/sphinx.mo +0 -0
  136. sphinx/locale/de/LC_MESSAGES/sphinx.po +2261 -2156
  137. sphinx/locale/de_DE/LC_MESSAGES/sphinx.mo +0 -0
  138. sphinx/locale/de_DE/LC_MESSAGES/sphinx.po +2045 -1940
  139. sphinx/locale/el/LC_MESSAGES/sphinx.mo +0 -0
  140. sphinx/locale/el/LC_MESSAGES/sphinx.po +2604 -2499
  141. sphinx/locale/en_DE/LC_MESSAGES/sphinx.mo +0 -0
  142. sphinx/locale/en_DE/LC_MESSAGES/sphinx.po +2045 -1940
  143. sphinx/locale/en_FR/LC_MESSAGES/sphinx.mo +0 -0
  144. sphinx/locale/en_FR/LC_MESSAGES/sphinx.po +2045 -1940
  145. sphinx/locale/en_GB/LC_MESSAGES/sphinx.mo +0 -0
  146. sphinx/locale/en_GB/LC_MESSAGES/sphinx.po +2631 -2526
  147. sphinx/locale/en_HK/LC_MESSAGES/sphinx.mo +0 -0
  148. sphinx/locale/en_HK/LC_MESSAGES/sphinx.po +2045 -1940
  149. sphinx/locale/eo/LC_MESSAGES/sphinx.mo +0 -0
  150. sphinx/locale/eo/LC_MESSAGES/sphinx.po +2078 -1973
  151. sphinx/locale/es/LC_MESSAGES/sphinx.mo +0 -0
  152. sphinx/locale/es/LC_MESSAGES/sphinx.po +2633 -2528
  153. sphinx/locale/es_CO/LC_MESSAGES/sphinx.mo +0 -0
  154. sphinx/locale/es_CO/LC_MESSAGES/sphinx.po +2045 -1940
  155. sphinx/locale/et/LC_MESSAGES/sphinx.mo +0 -0
  156. sphinx/locale/et/LC_MESSAGES/sphinx.po +2449 -2344
  157. sphinx/locale/eu/LC_MESSAGES/sphinx.mo +0 -0
  158. sphinx/locale/eu/LC_MESSAGES/sphinx.po +2241 -2136
  159. sphinx/locale/fa/LC_MESSAGES/sphinx.mo +0 -0
  160. sphinx/locale/fa/LC_MESSAGES/sphinx.po +504 -500
  161. sphinx/locale/fi/LC_MESSAGES/sphinx.mo +0 -0
  162. sphinx/locale/fi/LC_MESSAGES/sphinx.po +499 -495
  163. sphinx/locale/fr/LC_MESSAGES/sphinx.mo +0 -0
  164. sphinx/locale/fr/LC_MESSAGES/sphinx.po +513 -509
  165. sphinx/locale/fr_FR/LC_MESSAGES/sphinx.mo +0 -0
  166. sphinx/locale/fr_FR/LC_MESSAGES/sphinx.po +499 -495
  167. sphinx/locale/gl/LC_MESSAGES/sphinx.mo +0 -0
  168. sphinx/locale/gl/LC_MESSAGES/sphinx.po +2644 -2539
  169. sphinx/locale/he/LC_MESSAGES/sphinx.mo +0 -0
  170. sphinx/locale/he/LC_MESSAGES/sphinx.po +499 -495
  171. sphinx/locale/hi/LC_MESSAGES/sphinx.mo +0 -0
  172. sphinx/locale/hi/LC_MESSAGES/sphinx.po +504 -500
  173. sphinx/locale/hi_IN/LC_MESSAGES/sphinx.mo +0 -0
  174. sphinx/locale/hi_IN/LC_MESSAGES/sphinx.po +499 -495
  175. sphinx/locale/hr/LC_MESSAGES/sphinx.mo +0 -0
  176. sphinx/locale/hr/LC_MESSAGES/sphinx.po +501 -497
  177. sphinx/locale/hu/LC_MESSAGES/sphinx.mo +0 -0
  178. sphinx/locale/hu/LC_MESSAGES/sphinx.po +499 -495
  179. sphinx/locale/id/LC_MESSAGES/sphinx.mo +0 -0
  180. sphinx/locale/id/LC_MESSAGES/sphinx.po +2609 -2504
  181. sphinx/locale/is/LC_MESSAGES/sphinx.mo +0 -0
  182. sphinx/locale/is/LC_MESSAGES/sphinx.po +499 -495
  183. sphinx/locale/it/LC_MESSAGES/sphinx.mo +0 -0
  184. sphinx/locale/it/LC_MESSAGES/sphinx.po +2265 -2160
  185. sphinx/locale/ja/LC_MESSAGES/sphinx.mo +0 -0
  186. sphinx/locale/ja/LC_MESSAGES/sphinx.po +2621 -2516
  187. sphinx/locale/ka/LC_MESSAGES/sphinx.mo +0 -0
  188. sphinx/locale/ka/LC_MESSAGES/sphinx.po +2567 -2462
  189. sphinx/locale/ko/LC_MESSAGES/sphinx.mo +0 -0
  190. sphinx/locale/ko/LC_MESSAGES/sphinx.po +2631 -2526
  191. sphinx/locale/lt/LC_MESSAGES/sphinx.mo +0 -0
  192. sphinx/locale/lt/LC_MESSAGES/sphinx.po +2214 -2109
  193. sphinx/locale/lv/LC_MESSAGES/sphinx.mo +0 -0
  194. sphinx/locale/lv/LC_MESSAGES/sphinx.po +2218 -2113
  195. sphinx/locale/mk/LC_MESSAGES/sphinx.mo +0 -0
  196. sphinx/locale/mk/LC_MESSAGES/sphinx.po +2088 -1983
  197. sphinx/locale/nb_NO/LC_MESSAGES/sphinx.mo +0 -0
  198. sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po +2247 -2142
  199. sphinx/locale/ne/LC_MESSAGES/sphinx.mo +0 -0
  200. sphinx/locale/ne/LC_MESSAGES/sphinx.po +2227 -2122
  201. sphinx/locale/nl/LC_MESSAGES/sphinx.mo +0 -0
  202. sphinx/locale/nl/LC_MESSAGES/sphinx.po +2316 -2211
  203. sphinx/locale/pl/LC_MESSAGES/sphinx.js +2 -2
  204. sphinx/locale/pl/LC_MESSAGES/sphinx.mo +0 -0
  205. sphinx/locale/pl/LC_MESSAGES/sphinx.po +2442 -2336
  206. sphinx/locale/pt/LC_MESSAGES/sphinx.mo +0 -0
  207. sphinx/locale/pt/LC_MESSAGES/sphinx.po +2045 -1940
  208. sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo +0 -0
  209. sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po +2657 -2552
  210. sphinx/locale/pt_PT/LC_MESSAGES/sphinx.mo +0 -0
  211. sphinx/locale/pt_PT/LC_MESSAGES/sphinx.po +2243 -2138
  212. sphinx/locale/ro/LC_MESSAGES/sphinx.mo +0 -0
  213. sphinx/locale/ro/LC_MESSAGES/sphinx.po +2244 -2139
  214. sphinx/locale/ru/LC_MESSAGES/sphinx.js +1 -1
  215. sphinx/locale/ru/LC_MESSAGES/sphinx.mo +0 -0
  216. sphinx/locale/ru/LC_MESSAGES/sphinx.po +2660 -2555
  217. sphinx/locale/si/LC_MESSAGES/sphinx.mo +0 -0
  218. sphinx/locale/si/LC_MESSAGES/sphinx.po +2134 -2029
  219. sphinx/locale/sk/LC_MESSAGES/sphinx.mo +0 -0
  220. sphinx/locale/sk/LC_MESSAGES/sphinx.po +2614 -2509
  221. sphinx/locale/sl/LC_MESSAGES/sphinx.mo +0 -0
  222. sphinx/locale/sl/LC_MESSAGES/sphinx.po +2167 -2062
  223. sphinx/locale/sphinx.pot +2069 -1964
  224. sphinx/locale/sq/LC_MESSAGES/sphinx.mo +0 -0
  225. sphinx/locale/sq/LC_MESSAGES/sphinx.po +2661 -2556
  226. sphinx/locale/sr/LC_MESSAGES/sphinx.mo +0 -0
  227. sphinx/locale/sr/LC_MESSAGES/sphinx.po +2213 -2108
  228. sphinx/locale/sv/LC_MESSAGES/sphinx.mo +0 -0
  229. sphinx/locale/sv/LC_MESSAGES/sphinx.po +2229 -2124
  230. sphinx/locale/te/LC_MESSAGES/sphinx.mo +0 -0
  231. sphinx/locale/te/LC_MESSAGES/sphinx.po +2045 -1940
  232. sphinx/locale/tr/LC_MESSAGES/sphinx.mo +0 -0
  233. sphinx/locale/tr/LC_MESSAGES/sphinx.po +2608 -2503
  234. sphinx/locale/uk_UA/LC_MESSAGES/sphinx.mo +0 -0
  235. sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po +2167 -2062
  236. sphinx/locale/ur/LC_MESSAGES/sphinx.mo +0 -0
  237. sphinx/locale/ur/LC_MESSAGES/sphinx.po +2045 -1940
  238. sphinx/locale/vi/LC_MESSAGES/sphinx.mo +0 -0
  239. sphinx/locale/vi/LC_MESSAGES/sphinx.po +2204 -2099
  240. sphinx/locale/yue/LC_MESSAGES/sphinx.mo +0 -0
  241. sphinx/locale/yue/LC_MESSAGES/sphinx.po +2045 -1940
  242. sphinx/locale/zh_HK/LC_MESSAGES/sphinx.mo +0 -0
  243. sphinx/locale/zh_HK/LC_MESSAGES/sphinx.po +2045 -1940
  244. sphinx/locale/zh_TW/LC_MESSAGES/sphinx.mo +0 -0
  245. sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po +2659 -2554
  246. sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.mo +0 -0
  247. sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.po +2045 -1940
  248. sphinx/parsers.py +8 -7
  249. sphinx/project.py +2 -2
  250. sphinx/pycode/__init__.py +31 -21
  251. sphinx/pycode/ast.py +6 -3
  252. sphinx/pycode/parser.py +14 -8
  253. sphinx/pygments_styles.py +4 -5
  254. sphinx/registry.py +192 -92
  255. sphinx/roles.py +58 -7
  256. sphinx/search/__init__.py +75 -54
  257. sphinx/search/en.py +11 -13
  258. sphinx/search/fi.py +1 -1
  259. sphinx/search/ja.py +8 -6
  260. sphinx/search/nl.py +1 -1
  261. sphinx/search/zh.py +19 -21
  262. sphinx/testing/fixtures.py +26 -29
  263. sphinx/testing/path.py +26 -62
  264. sphinx/testing/restructuredtext.py +14 -8
  265. sphinx/testing/util.py +21 -19
  266. sphinx/texinputs/make.bat.jinja +50 -50
  267. sphinx/texinputs/sphinx.sty +4 -3
  268. sphinx/texinputs/sphinxlatexadmonitions.sty +1 -1
  269. sphinx/texinputs/sphinxlatexobjects.sty +29 -10
  270. sphinx/themes/basic/static/searchtools.js +8 -5
  271. sphinx/theming.py +49 -61
  272. sphinx/transforms/__init__.py +17 -38
  273. sphinx/transforms/compact_bullet_list.py +5 -3
  274. sphinx/transforms/i18n.py +8 -21
  275. sphinx/transforms/post_transforms/__init__.py +142 -93
  276. sphinx/transforms/post_transforms/code.py +5 -5
  277. sphinx/transforms/post_transforms/images.py +28 -24
  278. sphinx/transforms/references.py +3 -1
  279. sphinx/util/__init__.py +109 -60
  280. sphinx/util/_files.py +39 -23
  281. sphinx/util/_importer.py +4 -1
  282. sphinx/util/_inventory_file_reader.py +76 -0
  283. sphinx/util/_io.py +2 -2
  284. sphinx/util/_lines.py +6 -3
  285. sphinx/util/_pathlib.py +40 -2
  286. sphinx/util/build_phase.py +2 -0
  287. sphinx/util/cfamily.py +19 -14
  288. sphinx/util/console.py +44 -179
  289. sphinx/util/display.py +9 -10
  290. sphinx/util/docfields.py +140 -122
  291. sphinx/util/docstrings.py +1 -1
  292. sphinx/util/docutils.py +118 -77
  293. sphinx/util/fileutil.py +25 -26
  294. sphinx/util/http_date.py +2 -0
  295. sphinx/util/i18n.py +77 -64
  296. sphinx/util/images.py +8 -6
  297. sphinx/util/inspect.py +147 -38
  298. sphinx/util/inventory.py +215 -116
  299. sphinx/util/logging.py +33 -33
  300. sphinx/util/matching.py +12 -4
  301. sphinx/util/nodes.py +18 -13
  302. sphinx/util/osutil.py +38 -39
  303. sphinx/util/parallel.py +22 -13
  304. sphinx/util/parsing.py +2 -1
  305. sphinx/util/png.py +6 -2
  306. sphinx/util/requests.py +33 -2
  307. sphinx/util/rst.py +3 -2
  308. sphinx/util/tags.py +1 -1
  309. sphinx/util/template.py +18 -10
  310. sphinx/util/texescape.py +8 -6
  311. sphinx/util/typing.py +148 -122
  312. sphinx/versioning.py +3 -3
  313. sphinx/writers/html.py +3 -1
  314. sphinx/writers/html5.py +63 -52
  315. sphinx/writers/latex.py +83 -67
  316. sphinx/writers/manpage.py +19 -38
  317. sphinx/writers/texinfo.py +47 -47
  318. sphinx/writers/text.py +50 -32
  319. sphinx/writers/xml.py +11 -8
  320. {sphinx-8.1.2.dist-info → sphinx-8.2.0.dist-info}/LICENSE.rst +1 -1
  321. {sphinx-8.1.2.dist-info → sphinx-8.2.0.dist-info}/METADATA +25 -15
  322. sphinx-8.2.0.dist-info/RECORD +606 -0
  323. {sphinx-8.1.2.dist-info → sphinx-8.2.0.dist-info}/WHEEL +1 -1
  324. sphinx/builders/html/transforms.py +0 -90
  325. sphinx/ext/apidoc.py +0 -721
  326. sphinx/util/exceptions.py +0 -74
  327. sphinx-8.1.2.dist-info/RECORD +0 -598
  328. {sphinx-8.1.2.dist-info → sphinx-8.2.0.dist-info}/entry_points.txt +0 -0
sphinx/testing/path.py CHANGED
@@ -4,16 +4,17 @@ import os
4
4
  import shutil
5
5
  import sys
6
6
  import warnings
7
- from typing import IO, TYPE_CHECKING, Any
7
+ from typing import TYPE_CHECKING
8
8
 
9
9
  from sphinx.deprecation import RemovedInSphinx90Warning
10
10
 
11
11
  if TYPE_CHECKING:
12
12
  import builtins
13
13
  from collections.abc import Callable
14
+ from typing import IO, Any
14
15
 
15
16
  warnings.warn(
16
- "'sphinx.testing.path' is deprecated. " "Use 'os.path' or 'pathlib' instead.",
17
+ "'sphinx.testing.path' is deprecated. Use 'os.path' or 'pathlib' instead.",
17
18
  RemovedInSphinx90Warning,
18
19
  stacklevel=2,
19
20
  )
@@ -32,57 +33,41 @@ def getumask() -> int:
32
33
  UMASK = getumask()
33
34
 
34
35
 
35
- class path(str):
36
- """
37
- Represents a path which behaves like a string.
38
- """
36
+ class path(str): # NoQA: FURB189
37
+ """Represents a path which behaves like a string."""
39
38
 
40
39
  __slots__ = ()
41
40
 
42
41
  @property
43
42
  def parent(self) -> path:
44
- """
45
- The name of the directory the file or directory is in.
46
- """
43
+ """The name of the directory the file or directory is in."""
47
44
  return self.__class__(os.path.dirname(self))
48
45
 
49
46
  def basename(self) -> str:
50
47
  return os.path.basename(self)
51
48
 
52
49
  def abspath(self) -> path:
53
- """
54
- Returns the absolute path.
55
- """
50
+ """Returns the absolute path."""
56
51
  return self.__class__(os.path.abspath(self))
57
52
 
58
53
  def isabs(self) -> bool:
59
- """
60
- Returns ``True`` if the path is absolute.
61
- """
54
+ """Returns ``True`` if the path is absolute."""
62
55
  return os.path.isabs(self)
63
56
 
64
57
  def isdir(self) -> bool:
65
- """
66
- Returns ``True`` if the path is a directory.
67
- """
58
+ """Returns ``True`` if the path is a directory."""
68
59
  return os.path.isdir(self)
69
60
 
70
61
  def isfile(self) -> bool:
71
- """
72
- Returns ``True`` if the path is a file.
73
- """
62
+ """Returns ``True`` if the path is a file."""
74
63
  return os.path.isfile(self)
75
64
 
76
65
  def islink(self) -> bool:
77
- """
78
- Returns ``True`` if the path is a symbolic link.
79
- """
66
+ """Returns ``True`` if the path is a symbolic link."""
80
67
  return os.path.islink(self)
81
68
 
82
69
  def ismount(self) -> bool:
83
- """
84
- Returns ``True`` if the path is a mount point.
85
- """
70
+ """Returns ``True`` if the path is a mount point."""
86
71
  return os.path.ismount(self)
87
72
 
88
73
  def rmtree(
@@ -90,8 +75,7 @@ class path(str):
90
75
  ignore_errors: bool = False,
91
76
  onerror: Callable[[Callable[..., Any], str, Any], object] | None = None,
92
77
  ) -> None:
93
- """
94
- Removes the file or directory and any files or directories it may
78
+ """Removes the file or directory and any files or directories it may
95
79
  contain.
96
80
 
97
81
  :param ignore_errors:
@@ -108,8 +92,7 @@ class path(str):
108
92
  shutil.rmtree(self, ignore_errors=ignore_errors, onerror=onerror)
109
93
 
110
94
  def copytree(self, destination: str, symlinks: bool = False) -> None:
111
- """
112
- Recursively copy a directory to the given `destination`. If the given
95
+ """Recursively copy a directory to the given `destination`. If the given
113
96
  `destination` does not exist it will be created.
114
97
 
115
98
  :param symlinks:
@@ -130,8 +113,7 @@ class path(str):
130
113
  os.chmod(os.path.join(root, name), 0o644 & ~UMASK)
131
114
 
132
115
  def movetree(self, destination: str) -> None:
133
- """
134
- Recursively move the file or directory to the given `destination`
116
+ """Recursively move the file or directory to the given `destination`
135
117
  similar to the Unix "mv" command.
136
118
 
137
119
  If the `destination` is a file it may be overwritten depending on the
@@ -142,47 +124,36 @@ class path(str):
142
124
  move = movetree
143
125
 
144
126
  def unlink(self) -> None:
145
- """
146
- Removes a file.
147
- """
127
+ """Removes a file."""
148
128
  os.unlink(self)
149
129
 
150
130
  def stat(self) -> Any:
151
- """
152
- Returns a stat of the file.
153
- """
131
+ """Returns a stat of the file."""
154
132
  return os.stat(self)
155
133
 
156
134
  def utime(self, arg: Any) -> None:
157
135
  os.utime(self, arg)
158
136
 
159
137
  def open(self, mode: str = 'r', **kwargs: Any) -> IO[str]:
160
- return open(self, mode, **kwargs) # NoQA: SIM115
138
+ return open(self, mode, **kwargs)
161
139
 
162
140
  def write_text(self, text: str, encoding: str = 'utf-8', **kwargs: Any) -> None:
163
- """
164
- Writes the given `text` to the file.
165
- """
141
+ """Writes the given `text` to the file."""
166
142
  with open(self, 'w', encoding=encoding, **kwargs) as f:
167
143
  f.write(text)
168
144
 
169
145
  def read_text(self, encoding: str = 'utf-8', **kwargs: Any) -> str:
170
- """
171
- Returns the text in the file.
172
- """
146
+ """Returns the text in the file."""
173
147
  with open(self, encoding=encoding, **kwargs) as f:
174
148
  return f.read()
175
149
 
176
150
  def read_bytes(self) -> builtins.bytes:
177
- """
178
- Returns the bytes in the file.
179
- """
151
+ """Returns the bytes in the file."""
180
152
  with open(self, mode='rb') as f:
181
153
  return f.read()
182
154
 
183
155
  def write_bytes(self, bytes: bytes, append: bool = False) -> None:
184
- """
185
- Writes the given `bytes` to the file.
156
+ """Writes the given `bytes` to the file.
186
157
 
187
158
  :param append:
188
159
  If ``True`` given `bytes` are added at the end of the file.
@@ -195,28 +166,21 @@ class path(str):
195
166
  f.write(bytes)
196
167
 
197
168
  def exists(self) -> bool:
198
- """
199
- Returns ``True`` if the path exist.
200
- """
169
+ """Returns ``True`` if the path exist."""
201
170
  return os.path.exists(self)
202
171
 
203
172
  def lexists(self) -> bool:
204
- """
205
- Returns ``True`` if the path exists unless it is a broken symbolic
173
+ """Returns ``True`` if the path exists unless it is a broken symbolic
206
174
  link.
207
175
  """
208
176
  return os.path.lexists(self)
209
177
 
210
178
  def makedirs(self, mode: int = 0o777, exist_ok: bool = False) -> None:
211
- """
212
- Recursively create directories.
213
- """
179
+ """Recursively create directories."""
214
180
  os.makedirs(self, mode, exist_ok=exist_ok)
215
181
 
216
182
  def joinpath(self, *args: Any) -> path:
217
- """
218
- Joins the path with the argument given and returns the result.
219
- """
183
+ """Joins the path with the argument given and returns the result."""
220
184
  return self.__class__(os.path.join(self, *map(self.__class__, args)))
221
185
 
222
186
  def listdir(self) -> list[str]:
@@ -1,30 +1,36 @@
1
- from os import path
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
2
4
 
3
- from docutils import nodes
4
5
  from docutils.core import publish_doctree
5
6
 
6
- from sphinx.application import Sphinx
7
7
  from sphinx.io import SphinxStandaloneReader
8
8
  from sphinx.parsers import RSTParser
9
9
  from sphinx.util.docutils import sphinx_domains
10
10
 
11
+ if TYPE_CHECKING:
12
+ from docutils import nodes
13
+
14
+ from sphinx.application import Sphinx
15
+
11
16
 
12
17
  def parse(app: Sphinx, text: str, docname: str = 'index') -> nodes.document:
13
18
  """Parse a string as reStructuredText with Sphinx application."""
19
+ env = app.env
14
20
  try:
15
- app.env.temp_data['docname'] = docname
21
+ app.env.current_document.docname = docname
16
22
  reader = SphinxStandaloneReader()
17
23
  reader.setup(app)
18
24
  parser = RSTParser()
19
25
  parser.set_application(app)
20
- with sphinx_domains(app.env):
26
+ with sphinx_domains(env):
21
27
  return publish_doctree(
22
28
  text,
23
- path.join(app.srcdir, docname + '.rst'),
29
+ str(app.srcdir / f'{docname}.rst'),
24
30
  reader=reader,
25
31
  parser=parser,
26
32
  settings_overrides={
27
- 'env': app.env,
33
+ 'env': env,
28
34
  'gettext_compact': True,
29
35
  'input_encoding': 'utf-8',
30
36
  'output_encoding': 'unicode',
@@ -32,4 +38,4 @@ def parse(app: Sphinx, text: str, docname: str = 'index') -> nodes.document:
32
38
  },
33
39
  )
34
40
  finally:
35
- app.env.temp_data.pop('docname', None)
41
+ env.current_document.docname = ''
sphinx/testing/util.py CHANGED
@@ -4,8 +4,6 @@ from __future__ import annotations
4
4
 
5
5
  __all__ = ('SphinxTestApp', 'SphinxTestAppWrapperForSkipBuilding')
6
6
 
7
- import contextlib
8
- import os
9
7
  import sys
10
8
  from io import StringIO
11
9
  from types import MappingProxyType
@@ -17,10 +15,11 @@ from docutils.parsers.rst import directives, roles
17
15
  import sphinx.application
18
16
  import sphinx.locale
19
17
  import sphinx.pycode
20
- from sphinx.util.console import strip_colors
18
+ from sphinx._cli.util.errors import strip_escape_sequences
21
19
  from sphinx.util.docutils import additional_nodes
22
20
 
23
21
  if TYPE_CHECKING:
22
+ import os
24
23
  from collections.abc import Mapping, Sequence
25
24
  from pathlib import Path
26
25
  from typing import Any
@@ -40,9 +39,9 @@ def assert_node(node: Node, cls: Any = None, xpath: str = '', **kwargs: Any) ->
40
39
  assert (
41
40
  isinstance(node, nodes.Element)
42
41
  ), f'The node{xpath} does not have any children' # fmt: skip
43
- assert (
44
- len(node) == 1
45
- ), f'The node{xpath} has {len(node)} child nodes, not one'
42
+ assert len(node) == 1, (
43
+ f'The node{xpath} has {len(node)} child nodes, not one'
44
+ )
46
45
  assert_node(node[0], cls[1:], xpath=xpath + '[0]', **kwargs)
47
46
  elif isinstance(cls, tuple):
48
47
  assert (
@@ -71,9 +70,9 @@ def assert_node(node: Node, cls: Any = None, xpath: str = '', **kwargs: Any) ->
71
70
  if (key := key.replace('_', '-')) not in node:
72
71
  msg = f'The node{xpath} does not have {key!r} attribute: {node!r}'
73
72
  raise AssertionError(msg)
74
- assert (
75
- node[key] == value
76
- ), f'The node{xpath}[{key}] is not {value!r}: {node[key]!r}'
73
+ assert node[key] == value, (
74
+ f'The node{xpath}[{key}] is not {value!r}: {node[key]!r}'
75
+ )
77
76
 
78
77
 
79
78
  # keep this to restrict the API usage and to have a correct return type
@@ -224,15 +223,16 @@ class SphinxTestApp(sphinx.application.Sphinx):
224
223
  def cleanup(self, doctrees: bool = False) -> None:
225
224
  sys.path[:] = self._saved_path
226
225
  _clean_up_global_state()
227
- with contextlib.suppress(FileNotFoundError):
228
- os.remove(self.docutils_conf_path)
226
+ try:
227
+ self.docutils_conf_path.unlink(missing_ok=True)
228
+ except OSError as exc:
229
+ if exc.errno != 30: # Ignore "read-only file system" errors
230
+ raise
229
231
 
230
232
  def __repr__(self) -> str:
231
233
  return f'<{self.__class__.__name__} buildername={self._builder_name!r}>'
232
234
 
233
- def build(
234
- self, force_all: bool = False, filenames: list[str] | None = None
235
- ) -> None:
235
+ def build(self, force_all: bool = False, filenames: Sequence[Path] = ()) -> None:
236
236
  self.env._pickled_doctree_cache.clear()
237
237
  super().build(force_all, filenames)
238
238
 
@@ -244,10 +244,8 @@ class SphinxTestAppWrapperForSkipBuilding(SphinxTestApp):
244
244
  if it has already been built and there are any output files.
245
245
  """
246
246
 
247
- def build(
248
- self, force_all: bool = False, filenames: list[str] | None = None
249
- ) -> None:
250
- if not os.listdir(self.outdir):
247
+ def build(self, force_all: bool = False, filenames: Sequence[Path] = ()) -> None:
248
+ if not list(self.outdir.iterdir()):
251
249
  # if listdir is empty, do build.
252
250
  super().build(force_all, filenames)
253
251
  # otherwise, we can use built cache
@@ -273,7 +271,11 @@ def _clean_up_global_state() -> None:
273
271
 
274
272
  # deprecated name -> (object to return, canonical path or '', removal version)
275
273
  _DEPRECATED_OBJECTS: dict[str, tuple[Any, str, tuple[int, int]]] = {
276
- 'strip_escseq': (strip_colors, 'sphinx.util.console.strip_colors', (9, 0)),
274
+ 'strip_escseq': (
275
+ strip_escape_sequences,
276
+ 'sphinx.util.console.strip_escape_sequences',
277
+ (9, 0),
278
+ ),
277
279
  }
278
280
 
279
281
 
@@ -1,50 +1,50 @@
1
- @ECHO OFF
2
-
3
- REM Command file for Sphinx documentation
4
-
5
- pushd %~dp0
6
-
7
- {% if latex_engine in ('platex', 'uplatex') -%}
8
- REM latexmkrc is read then overridden by latexmkjarc
9
- set PDFLATEX=latexmk -r latexmkjarc -pdfdvi -dvi- -ps-
10
- {% else -%}
11
- set PDFLATEX=latexmk -pdf -dvi- -ps-
12
- {% endif %}
13
- set "LATEXOPTS= "
14
-
15
- {% if xindy_use -%}
16
- set XINDYOPTS={{ xindy_lang_option }} -M sphinx.xdy
17
- {% if latex_engine == 'pdflatex' -%}
18
- set XINDYOPTS=%XINDYOPTS% -M LICRlatin2utf8.xdy
19
- {% if xindy_cyrillic -%}
20
- set XINDYOPTS=%XINDYOPTS% -M LICRcyr2utf8.xdy
21
- {% endif -%}
22
- {% endif -%}
23
- {% if xindy_cyrillic -%}
24
- set XINDYOPTS=%XINDYOPTS% -M LatinRules.xdy
25
- {% endif -%}
26
- set XINDYOPTS=%XINDYOPTS% -I xelatex
27
- {% endif -%}
28
-
29
-
30
- if "%1" == "" goto all-pdf
31
-
32
- if "%1" == "all-pdf" (
33
- :all-pdf
34
- for %%i in (*.tex) do (
35
- %PDFLATEX% %LATEXMKOPTS% %%i
36
- )
37
- goto end
38
- )
39
-
40
- if "%1" == "all-pdf-ja" (
41
- goto all-pdf
42
- )
43
-
44
- if "%1" == "clean" (
45
- del /q /s *.dvi *.log *.ind *.aux *.toc *.syn *.idx *.out *.ilg *.pla *.ps *.tar *.tar.gz *.tar.bz2 *.tar.xz *.fls *.fdb_latexmk
46
- goto end
47
- )
48
-
49
- :end
50
- popd
1
+ @ECHO OFF
2
+
3
+ REM Command file for Sphinx documentation
4
+
5
+ pushd %~dp0
6
+
7
+ {% if latex_engine in ('platex', 'uplatex') -%}
8
+ REM latexmkrc is read then overridden by latexmkjarc
9
+ set PDFLATEX=latexmk -r latexmkjarc -pdfdvi -dvi- -ps-
10
+ {% else -%}
11
+ set PDFLATEX=latexmk -pdf -dvi- -ps-
12
+ {% endif %}
13
+ set "LATEXOPTS= "
14
+
15
+ {% if xindy_use -%}
16
+ set XINDYOPTS={{ xindy_lang_option }} -M sphinx.xdy
17
+ {% if latex_engine == 'pdflatex' -%}
18
+ set XINDYOPTS=%XINDYOPTS% -M LICRlatin2utf8.xdy
19
+ {% if xindy_cyrillic -%}
20
+ set XINDYOPTS=%XINDYOPTS% -M LICRcyr2utf8.xdy
21
+ {% endif -%}
22
+ {% endif -%}
23
+ {% if xindy_cyrillic -%}
24
+ set XINDYOPTS=%XINDYOPTS% -M LatinRules.xdy
25
+ {% endif -%}
26
+ set XINDYOPTS=%XINDYOPTS% -I xelatex
27
+ {% endif -%}
28
+
29
+
30
+ if "%1" == "" goto all-pdf
31
+
32
+ if "%1" == "all-pdf" (
33
+ :all-pdf
34
+ for %%i in (*.tex) do (
35
+ %PDFLATEX% %LATEXMKOPTS% %%i
36
+ )
37
+ goto end
38
+ )
39
+
40
+ if "%1" == "all-pdf-ja" (
41
+ goto all-pdf
42
+ )
43
+
44
+ if "%1" == "clean" (
45
+ del /q /s *.dvi *.log *.ind *.aux *.toc *.syn *.idx *.out *.ilg *.pla *.ps *.tar *.tar.gz *.tar.bz2 *.tar.xz *.fls *.fdb_latexmk
46
+ goto end
47
+ )
48
+
49
+ :end
50
+ popd
@@ -9,7 +9,7 @@
9
9
  % by the Sphinx LaTeX writer.
10
10
 
11
11
  \NeedsTeXFormat{LaTeX2e}[1995/12/01]
12
- \ProvidesPackage{sphinx}[2024/10/11 v8.1.1 Sphinx LaTeX package (sphinx-doc)]
12
+ \ProvidesPackage{sphinx}[2024/11/23 v8.2.0 Sphinx LaTeX package (sphinx-doc)]
13
13
 
14
14
  % provides \ltx@ifundefined
15
15
  % (many packages load ltxcmds: graphicx does for pdftex and lualatex but
@@ -1098,12 +1098,13 @@
1098
1098
  % Some of these defaults got already set. But we now list them all explicitly
1099
1099
  % for a complete initial configuration of reset storage.
1100
1100
  % At 7.4.0, \fboxrule and \fboxsep replaced by 0.4pt and 3pt which are anyhow
1101
- % the defaults for these LaTeX dimensions.
1101
+ % the defaults for these LaTeX dimensions. 8.2.0 corrected border-radius
1102
+ % default back to 3pt (\fboxsep) not 0.4pt (\fboxrule).
1102
1103
  \let\spx@boxes@sphinxbox@defaults\@gobble
1103
1104
  \sphinxboxsetup{%
1104
1105
  border-width=0.4pt,
1105
1106
  padding=3pt,
1106
- border-radius=0.4pt,
1107
+ border-radius=3pt,
1107
1108
  box-shadow=none,
1108
1109
  % MEMO: as xcolor is loaded, \spx@defineorletcolor has a "\colorlet" branch
1109
1110
  % which makes this syntax acceptable and avoids duplicating here the values.
@@ -32,7 +32,7 @@
32
32
  % sphinxlatexshadowbox.sty, and handles both "with icon" and "without
33
33
  % icon" situations).
34
34
  %
35
- % The sphinxlightbox environment is kept for backward compatiblity, for user
35
+ % The sphinxlightbox environment is kept for backward compatibility, for user
36
36
  % custom code which used it via custom definitions done in preamble or via
37
37
  % raw latex directive.
38
38
  % MEMO: here is for example how sphinxnote was formerly defined:
@@ -1,7 +1,7 @@
1
1
  %% MODULE RELEASE DATA AND OBJECT DESCRIPTIONS
2
2
  %
3
3
  % change this info string if making any custom modification
4
- \ProvidesPackage{sphinxlatexobjects}[2023/07/23 documentation environments]
4
+ \ProvidesPackage{sphinxlatexobjects}[2025/02/11 documentation environments]
5
5
 
6
6
  % Provides support for this output mark-up from Sphinx latex writer:
7
7
  %
@@ -279,18 +279,37 @@
279
279
  \newcommand{\pysigstopmultiline}{\sphinxsigismultilinefalse\itemsep\sphinxsignaturesep}%
280
280
 
281
281
  % Production lists
282
+ % This simply outputs the lines as is, in monospace font. Refers #13326.
283
+ % (the left padding for multi-line alignment is from the nodes themselves,
284
+ % and latex is configured below to obey such horizontal whitespace).
285
+ %
286
+ % - The legacy code used longtable and hardcoded the separator as ::=
287
+ % via dedicated macros defined by the environment itself.
288
+ % - Here the separator is part of the node. Any extra LaTeX mark-up would
289
+ % have to originate from the writer itself to decorate it.
290
+ % - The legacy code used strangely \parindent and \indent. Possibly
291
+ % (unchecked) due to an earlier tabular usage, but a longtable does not
292
+ % work in paragraph mode, so \parindent was without effect and
293
+ % \indent only caused some extra blank line above display.
294
+ % - The table had some whitespace on its left, which we imitate here via
295
+ % \parindent usage (which works in our context...).
282
296
  %
283
297
  \newenvironment{productionlist}{%
284
- % \def\sphinxoptional##1{{\Large[}##1{\Large]}}
285
- \def\production##1##2{\\\sphinxcode{\sphinxupquote{##1}}&::=&\sphinxcode{\sphinxupquote{##2}}}%
286
- \def\productioncont##1{\\& &\sphinxcode{\sphinxupquote{##1}}}%
287
- \parindent=2em
288
- \indent
289
- \setlength{\LTpre}{0pt}%
290
- \setlength{\LTpost}{0pt}%
291
- \begin{longtable}[l]{lcl}
298
+ \bigskip % imitate close enough legacy vertical whitespace, which was
299
+ % visibly excessive
300
+ \ttfamily % needed for space tokens to have same width as letters
301
+ \parindent1em % width of a "quad", font-dependent, usually circa width of 2
302
+ % letters
303
+ \obeylines % line in = line out
304
+ \parskip\z@skip % prevent the parskip vertical whitespace between lines,
305
+ % which are technically to LaTeX now each its own paragraph
306
+ \@vobeyspaces % obey whitespace
307
+ % now a technicality to, only locally to this environment, prevent the
308
+ % suppression of indentation of first line, if it comes right after
309
+ % \section. Cf package indentfirst from which the code is borrowed.
310
+ \let\@afterindentfalse\@afterindenttrue\@afterindenttrue
292
311
  }{%
293
- \end{longtable}
312
+ \par % does not hurt...
294
313
  }
295
314
 
296
315
  % Definition lists; requested by AMK for HOWTO documents. Probably useful
@@ -513,9 +513,11 @@ const Search = {
513
513
  // perform the search on the required terms
514
514
  searchTerms.forEach((word) => {
515
515
  const files = [];
516
+ // find documents, if any, containing the query word in their text/title term indices
517
+ // use Object.hasOwnProperty to avoid mismatching against prototype properties
516
518
  const arr = [
517
- { files: terms[word], score: Scorer.term },
518
- { files: titleTerms[word], score: Scorer.title },
519
+ { files: terms.hasOwnProperty(word) ? terms[word] : undefined, score: Scorer.term },
520
+ { files: titleTerms.hasOwnProperty(word) ? titleTerms[word] : undefined, score: Scorer.title },
519
521
  ];
520
522
  // add support for partial matches
521
523
  if (word.length > 2) {
@@ -547,8 +549,9 @@ const Search = {
547
549
 
548
550
  // set score for the word in each file
549
551
  recordFiles.forEach((file) => {
550
- if (!scoreMap.has(file)) scoreMap.set(file, {});
551
- scoreMap.get(file)[word] = record.score;
552
+ if (!scoreMap.has(file)) scoreMap.set(file, new Map());
553
+ const fileScores = scoreMap.get(file);
554
+ fileScores.set(word, record.score);
552
555
  });
553
556
  });
554
557
 
@@ -587,7 +590,7 @@ const Search = {
587
590
  break;
588
591
 
589
592
  // select one (max) score for the file.
590
- const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w]));
593
+ const score = Math.max(...wordList.map((w) => scoreMap.get(file).get(w)));
591
594
  // add result to the result list
592
595
  results.push([
593
596
  docNames[file],