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
@@ -1,11 +1,11 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import os
4
- from os import path
5
- from typing import TYPE_CHECKING, ClassVar, cast
4
+ from pathlib import Path
5
+ from typing import TYPE_CHECKING, cast
6
6
 
7
7
  from docutils import nodes
8
- from docutils.nodes import Node, make_id
8
+ from docutils.nodes import make_id
9
9
  from docutils.parsers.rst import directives
10
10
  from docutils.parsers.rst.directives import images, tables
11
11
  from docutils.parsers.rst.directives.misc import Meta
@@ -16,9 +16,13 @@ from sphinx.locale import __
16
16
  from sphinx.util import logging
17
17
  from sphinx.util.docutils import SphinxDirective
18
18
  from sphinx.util.nodes import set_source_info
19
- from sphinx.util.osutil import SEP, os_path, relpath
19
+ from sphinx.util.osutil import SEP, relpath
20
20
 
21
21
  if TYPE_CHECKING:
22
+ from typing import ClassVar
23
+
24
+ from docutils.nodes import Node
25
+
22
26
  from sphinx.application import Sphinx
23
27
  from sphinx.util.typing import ExtensionMetadata, OptionSpec
24
28
 
@@ -38,7 +42,7 @@ class Figure(images.Figure): # type: ignore[misc]
38
42
  return result
39
43
 
40
44
  assert len(result) == 1
41
- figure_node = cast(nodes.figure, result[0])
45
+ figure_node = cast('nodes.figure', result[0])
42
46
  if name:
43
47
  # set ``name`` to figure_node if given
44
48
  self.options['name'] = name
@@ -46,7 +50,7 @@ class Figure(images.Figure): # type: ignore[misc]
46
50
 
47
51
  # copy lineno from image node
48
52
  if figure_node.line is None and len(figure_node) == 2:
49
- caption = cast(nodes.caption, figure_node[1])
53
+ caption = cast('nodes.caption', figure_node[1])
50
54
  figure_node.line = caption.line
51
55
 
52
56
  return [figure_node]
@@ -60,8 +64,8 @@ class CSVTable(tables.CSVTable): # type: ignore[misc]
60
64
  def run(self) -> list[Node]:
61
65
  if 'file' in self.options and self.options['file'].startswith((SEP, os.sep)):
62
66
  env = self.state.document.settings.env
63
- filename = self.options['file']
64
- if path.exists(filename):
67
+ filename = Path(self.options['file'])
68
+ if filename.exists():
65
69
  logger.warning(
66
70
  __(
67
71
  '":file:" option for csv-table directive now recognizes '
@@ -71,9 +75,9 @@ class CSVTable(tables.CSVTable): # type: ignore[misc]
71
75
  location=(env.docname, self.lineno),
72
76
  )
73
77
  else:
74
- abspath = path.join(env.srcdir, os_path(self.options['file'][1:]))
75
- docdir = path.dirname(env.doc2path(env.docname))
76
- self.options['file'] = relpath(abspath, docdir)
78
+ abspath = env.srcdir / self.options['file'][1:]
79
+ doc_dir = env.doc2path(env.docname).parent
80
+ self.options['file'] = relpath(abspath, doc_dir)
77
81
 
78
82
  return super().run()
79
83
 
@@ -115,8 +119,9 @@ class Code(SphinxDirective):
115
119
  # no highlight language specified. Then this directive refers the current
116
120
  # highlight setting via ``highlight`` directive or ``highlight_language``
117
121
  # configuration.
118
- node['language'] = self.env.temp_data.get(
119
- 'highlight_language', self.config.highlight_language
122
+ node['language'] = (
123
+ self.env.current_document.highlight_language
124
+ or self.config.highlight_language
120
125
  )
121
126
 
122
127
  if 'number-lines' in self.options:
@@ -138,10 +143,17 @@ class MathDirective(SphinxDirective):
138
143
  'label': directives.unchanged,
139
144
  'name': directives.unchanged,
140
145
  'class': directives.class_option,
146
+ 'no-wrap': directives.flag,
141
147
  'nowrap': directives.flag,
142
148
  }
143
149
 
144
150
  def run(self) -> list[Node]:
151
+ # Copy the old option name to the new one
152
+ # xref RemovedInSphinx90Warning
153
+ # deprecate nowrap in Sphinx 9.0
154
+ if 'no-wrap' not in self.options and 'nowrap' in self.options:
155
+ self.options['no-wrap'] = self.options['nowrap']
156
+
145
157
  latex = '\n'.join(self.content)
146
158
  if self.arguments and self.arguments[0]:
147
159
  latex = self.arguments[0] + '\n\n' + latex
@@ -153,8 +165,8 @@ class MathDirective(SphinxDirective):
153
165
  docname=self.env.docname,
154
166
  number=None,
155
167
  label=label,
156
- nowrap='nowrap' in self.options,
157
168
  )
169
+ node['no-wrap'] = node['nowrap'] = 'no-wrap' in self.options
158
170
  self.add_name(node)
159
171
  self.set_source_info(node)
160
172
 
@@ -163,10 +175,10 @@ class MathDirective(SphinxDirective):
163
175
  return ret
164
176
 
165
177
  def add_target(self, ret: list[Node]) -> None:
166
- node = cast(nodes.math_block, ret[0])
178
+ node = cast('nodes.math_block', ret[0])
167
179
 
168
180
  # assign label automatically if math_number_all enabled
169
- if node['label'] == '' or (self.config.math_number_all and not node['label']):
181
+ if node['label'] == '' or (self.config.math_number_all and not node['label']): # NoQA: PLC1901
170
182
  seq = self.env.new_serialno('sphinx.ext.math#equations')
171
183
  node['label'] = f'{self.env.docname}:{seq}'
172
184
 
@@ -13,7 +13,7 @@ from sphinx.domains._index import Index, IndexEntry
13
13
  from sphinx.locale import _
14
14
 
15
15
  if TYPE_CHECKING:
16
- from collections.abc import Callable, Iterable, Sequence, Set
16
+ from collections.abc import Iterable, Sequence, Set
17
17
  from typing import Any
18
18
 
19
19
  from docutils import nodes
@@ -36,8 +36,7 @@ __all__ = (
36
36
 
37
37
 
38
38
  class ObjType:
39
- """
40
- An ObjType is the description for a type of object that a domain can
39
+ """An ObjType is the description for a type of object that a domain can
41
40
  document. In the object_types attribute of Domain subclasses, object type
42
41
  names are mapped to instances of this class.
43
42
 
@@ -61,8 +60,7 @@ class ObjType:
61
60
 
62
61
 
63
62
  class Domain:
64
- """
65
- A Domain is meant to be a group of "object" description directives for
63
+ """A Domain is meant to be a group of "object" description directives for
66
64
  objects of a similar nature, and corresponding roles to create references to
67
65
  them. Examples would be Python modules, classes, functions etc., elements
68
66
  of a templating language, Sphinx roles and directives, etc.
@@ -100,16 +98,17 @@ class Domain:
100
98
  #: node_class -> (enum_node_type, title_getter)
101
99
  enumerable_nodes: dict[type[Node], tuple[str, TitleGetter | None]] = {}
102
100
  #: data value for a fresh environment
103
- initial_data: dict = {}
101
+ initial_data: dict[str, Any] = {}
104
102
  #: data value
105
103
  data: dict[str, Any]
106
104
  #: data version, bump this when the format of `self.data` changes
107
105
  data_version = 0
108
106
 
109
107
  def __init__(self, env: BuildEnvironment) -> None:
108
+ domain_data: dict[str, dict[str, Any]] = env.domaindata
110
109
  self.env: BuildEnvironment = env
111
- self._role_cache: dict[str, Callable] = {}
112
- self._directive_cache: dict[str, Callable] = {}
110
+ self._role_cache: dict[str, RoleFunction] = {}
111
+ self._directive_cache: dict[str, type[Directive]] = {}
113
112
  self._role2type: dict[str, list[str]] = {}
114
113
  self._type2role: dict[str, str] = {}
115
114
 
@@ -119,13 +118,13 @@ class Domain:
119
118
  self.roles = dict(self.roles)
120
119
  self.indices = list(self.indices)
121
120
 
122
- if self.name not in env.domaindata:
121
+ if self.name not in domain_data:
123
122
  assert isinstance(self.initial_data, dict)
124
123
  new_data = copy.deepcopy(self.initial_data)
125
124
  new_data['version'] = self.data_version
126
- self.data = env.domaindata[self.name] = new_data
125
+ self.data = domain_data[self.name] = new_data
127
126
  else:
128
- self.data = env.domaindata[self.name]
127
+ self.data = domain_data[self.name]
129
128
  if self.data['version'] != self.data_version:
130
129
  raise OSError('data of %r domain out of date' % self.label)
131
130
  for name, obj in self.object_types.items():
@@ -141,7 +140,7 @@ class Domain:
141
140
  std = self.env.domains.standard_domain
142
141
  for index in self.indices:
143
142
  if index.name and index.localname:
144
- docname = f"{self.name}-{index.name}"
143
+ docname = f'{self.name}-{index.name}'
145
144
  std.note_hyperlink_target(docname, docname, '', index.localname)
146
145
 
147
146
  def add_object_type(self, name: str, objtype: ObjType) -> None:
@@ -165,16 +164,23 @@ class Domain:
165
164
  return None
166
165
  fullname = f'{self.name}:{name}'
167
166
 
168
- def role_adapter(typ: str, rawtext: str, text: str, lineno: int,
169
- inliner: Inliner, options: dict | None = None,
170
- content: Sequence[str] = (),
171
- ) -> tuple[list[Node], list[nodes.system_message]]:
172
- return self.roles[name](fullname, rawtext, text, lineno,
173
- inliner, options or {}, content)
167
+ def role_adapter(
168
+ typ: str,
169
+ rawtext: str,
170
+ text: str,
171
+ lineno: int,
172
+ inliner: Inliner,
173
+ options: dict[str, Any] | None = None,
174
+ content: Sequence[str] = (),
175
+ ) -> tuple[list[Node], list[nodes.system_message]]:
176
+ return self.roles[name](
177
+ fullname, rawtext, text, lineno, inliner, options or {}, content
178
+ )
179
+
174
180
  self._role_cache[name] = role_adapter
175
181
  return role_adapter
176
182
 
177
- def directive(self, name: str) -> Callable | None:
183
+ def directive(self, name: str) -> type[Directive] | None:
178
184
  """Return a directive adapter class that always gives the registered
179
185
  directive its full name ('domain:name') as ``self.name``.
180
186
  """
@@ -189,6 +195,7 @@ class Domain:
189
195
  def run(self) -> list[Node]:
190
196
  self.name = fullname
191
197
  return super().run()
198
+
192
199
  self._directive_cache[name] = DirectiveAdapter
193
200
  return DirectiveAdapter
194
201
 
@@ -202,12 +209,15 @@ class Domain:
202
209
  """Merge in data regarding *docnames* from a different domaindata
203
210
  inventory (coming from a subprocess in parallel builds).
204
211
  """
205
- raise NotImplementedError('merge_domaindata must be implemented in %s '
206
- 'to be able to do parallel builds!' %
207
- self.__class__)
208
-
209
- def process_doc(self, env: BuildEnvironment, docname: str,
210
- document: nodes.document) -> None:
212
+ msg = (
213
+ f'merge_domaindata must be implemented in {self.__class__} '
214
+ 'to be able to do parallel builds!'
215
+ )
216
+ raise NotImplementedError(msg)
217
+
218
+ def process_doc(
219
+ self, env: BuildEnvironment, docname: str, document: nodes.document
220
+ ) -> None:
211
221
  """Process a document after it is read by the environment."""
212
222
  pass
213
223
 
@@ -221,9 +231,16 @@ class Domain:
221
231
  """
222
232
  pass
223
233
 
224
- def resolve_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder,
225
- typ: str, target: str, node: pending_xref, contnode: Element,
226
- ) -> Element | None:
234
+ def resolve_xref(
235
+ self,
236
+ env: BuildEnvironment,
237
+ fromdocname: str,
238
+ builder: Builder,
239
+ typ: str,
240
+ target: str,
241
+ node: pending_xref,
242
+ contnode: Element,
243
+ ) -> nodes.reference | None:
227
244
  """Resolve the pending_xref *node* with the given *typ* and *target*.
228
245
 
229
246
  This method should return a new node, to replace the xref node,
@@ -239,9 +256,15 @@ class Domain:
239
256
  """
240
257
  pass
241
258
 
242
- def resolve_any_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder,
243
- target: str, node: pending_xref, contnode: Element,
244
- ) -> list[tuple[str, Element]]:
259
+ def resolve_any_xref(
260
+ self,
261
+ env: BuildEnvironment,
262
+ fromdocname: str,
263
+ builder: Builder,
264
+ target: str,
265
+ node: pending_xref,
266
+ contnode: Element,
267
+ ) -> list[tuple[str, nodes.reference]]:
245
268
  """Resolve the pending_xref *node* with the given *target*.
246
269
 
247
270
  The reference comes from an "any" or similar role, which means that we
@@ -4,10 +4,9 @@ from typing import TYPE_CHECKING, overload
4
4
 
5
5
  if TYPE_CHECKING:
6
6
  from collections.abc import Iterable, Iterator, Mapping, Set
7
- from typing import Any, Final, Literal, NoReturn
7
+ from typing import Any, Final, Literal, NoReturn, Self
8
8
 
9
9
  from docutils import nodes
10
- from typing_extensions import Self
11
10
 
12
11
  from sphinx.domains import Domain
13
12
  from sphinx.domains.c import CDomain
@@ -23,6 +22,7 @@ if TYPE_CHECKING:
23
22
  from sphinx.environment import BuildEnvironment
24
23
  from sphinx.ext.duration import DurationDomain
25
24
  from sphinx.ext.todo import TodoDomain
25
+ from sphinx.registry import SphinxComponentRegistry
26
26
 
27
27
 
28
28
  class _DomainsContainer:
@@ -72,8 +72,10 @@ class _DomainsContainer:
72
72
  })
73
73
 
74
74
  @classmethod
75
- def _from_environment(cls, env: BuildEnvironment, /) -> Self:
76
- create_domains = env.app.registry.create_domains
75
+ def _from_environment(
76
+ cls, env: BuildEnvironment, /, *, registry: SphinxComponentRegistry
77
+ ) -> Self:
78
+ create_domains = registry.create_domains
77
79
  # Initialise domains
78
80
  if domains := {domain.name: domain for domain in create_domains(env)}:
79
81
  return cls(**domains) # type: ignore[arg-type]
@@ -188,6 +190,9 @@ class _DomainsContainer:
188
190
  return NotImplemented
189
191
  return self._domain_instances == other._domain_instances
190
192
 
193
+ def __hash__(self) -> int:
194
+ return hash(sorted(self._domain_instances.items()))
195
+
191
196
  def __setattr__(self, key: str, value: object) -> None:
192
197
  if key in self._core_domains:
193
198
  msg = f'{self.__class__.__name__!r} object does not support assignment to {key!r}'
@@ -203,47 +208,47 @@ class _DomainsContainer:
203
208
  # Mapping interface: builtin domains
204
209
 
205
210
  @overload
206
- def __getitem__(self, key: Literal['c']) -> CDomain: ... # NoQA: E704
211
+ def __getitem__(self, key: Literal['c']) -> CDomain: ...
207
212
 
208
213
  @overload
209
- def __getitem__(self, key: Literal['cpp']) -> CPPDomain: ... # NoQA: E704
214
+ def __getitem__(self, key: Literal['cpp']) -> CPPDomain: ...
210
215
 
211
216
  @overload
212
- def __getitem__(self, key: Literal['changeset']) -> ChangeSetDomain: ... # NoQA: E704
217
+ def __getitem__(self, key: Literal['changeset']) -> ChangeSetDomain: ...
213
218
 
214
219
  @overload
215
- def __getitem__(self, key: Literal['citation']) -> CitationDomain: ... # NoQA: E704
220
+ def __getitem__(self, key: Literal['citation']) -> CitationDomain: ...
216
221
 
217
222
  @overload
218
- def __getitem__(self, key: Literal['index']) -> IndexDomain: ... # NoQA: E704
223
+ def __getitem__(self, key: Literal['index']) -> IndexDomain: ...
219
224
 
220
225
  @overload
221
- def __getitem__(self, key: Literal['js']) -> JavaScriptDomain: ... # NoQA: E704
226
+ def __getitem__(self, key: Literal['js']) -> JavaScriptDomain: ...
222
227
 
223
228
  @overload
224
- def __getitem__(self, key: Literal['math']) -> MathDomain: ... # NoQA: E704
229
+ def __getitem__(self, key: Literal['math']) -> MathDomain: ...
225
230
 
226
231
  @overload
227
- def __getitem__(self, key: Literal['py']) -> PythonDomain: ... # NoQA: E704
232
+ def __getitem__(self, key: Literal['py']) -> PythonDomain: ...
228
233
 
229
234
  @overload
230
- def __getitem__(self, key: Literal['rst']) -> ReSTDomain: ... # NoQA: E704
235
+ def __getitem__(self, key: Literal['rst']) -> ReSTDomain: ...
231
236
 
232
237
  @overload
233
- def __getitem__(self, key: Literal['std']) -> StandardDomain: ... # NoQA: E704
238
+ def __getitem__(self, key: Literal['std']) -> StandardDomain: ...
234
239
 
235
240
  # Mapping interface: first-party domains
236
241
 
237
242
  @overload
238
- def __getitem__(self, key: Literal['duration']) -> DurationDomain: ... # NoQA: E704
243
+ def __getitem__(self, key: Literal['duration']) -> DurationDomain: ...
239
244
 
240
245
  @overload
241
- def __getitem__(self, key: Literal['todo']) -> TodoDomain: ... # NoQA: E704
246
+ def __getitem__(self, key: Literal['todo']) -> TodoDomain: ...
242
247
 
243
248
  # Mapping interface: third-party domains
244
249
 
245
250
  @overload
246
- def __getitem__(self, key: str) -> Domain: ... # NoQA: E704
251
+ def __getitem__(self, key: str) -> Domain: ...
247
252
 
248
253
  def __getitem__(self, key: str) -> Domain:
249
254
  if domain := getattr(self, key, None):
sphinx/domains/_index.py CHANGED
@@ -14,8 +14,7 @@ if TYPE_CHECKING:
14
14
 
15
15
 
16
16
  class IndexEntry(NamedTuple):
17
- """
18
- An index entry.
17
+ """An index entry.
19
18
 
20
19
  .. note::
21
20
 
@@ -53,8 +52,7 @@ class IndexEntry(NamedTuple):
53
52
 
54
53
 
55
54
  class Index(ABC):
56
- """
57
- An Index is the description for a domain-specific index. To add an index to
55
+ """An Index is the description for a domain-specific index. To add an index to
58
56
  a domain, subclass Index, overriding the three name attributes:
59
57
 
60
58
  * `name` is an identifier used for generating file names.
@@ -65,9 +63,9 @@ class Index(ABC):
65
63
  * `shortname` is a short name for the index, for use in the relation bar in
66
64
  HTML output. Can be empty to disable entries in the relation bar.
67
65
 
68
- and providing a :meth:`generate()` method. Then, add the index class to
66
+ and providing a :meth:`generate` method. Then, add the index class to
69
67
  your domain's `indices` list. Extensions can add indices to existing
70
- domains using :meth:`~sphinx.application.Sphinx.add_index_to_domain()`.
68
+ domains using :meth:`~sphinx.application.Sphinx.add_index_to_domain`.
71
69
 
72
70
  .. versionchanged:: 3.0
73
71
 
@@ -87,8 +85,7 @@ class Index(ABC):
87
85
 
88
86
  @abstractmethod
89
87
  def generate(
90
- self,
91
- docnames: Iterable[str] | None = None,
88
+ self, docnames: Iterable[str] | None = None
92
89
  ) -> tuple[list[tuple[str, list[IndexEntry]]], bool]:
93
90
  """Get entries for the index.
94
91