Sphinx 8.1.3__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 +829 -480
  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.3.dist-info → sphinx-8.2.0.dist-info}/LICENSE.rst +1 -1
  321. {sphinx-8.1.3.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.3.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.3.dist-info/RECORD +0 -598
  328. {sphinx-8.1.3.dist-info → sphinx-8.2.0.dist-info}/entry_points.txt +0 -0
sphinx/application.py CHANGED
@@ -6,19 +6,18 @@ Gracefully adapted from the TextPress system by Armin.
6
6
  from __future__ import annotations
7
7
 
8
8
  import contextlib
9
- import os
10
9
  import pickle
11
10
  import sys
12
11
  from collections import deque
13
12
  from io import StringIO
14
- from os import path
15
13
  from typing import TYPE_CHECKING, overload
16
14
 
17
- from docutils.parsers.rst import Directive, roles
15
+ from docutils.parsers.rst import roles
18
16
 
19
17
  import sphinx
20
18
  from sphinx import locale, package_dir
21
- from sphinx.config import ENUM, Config, _ConfigRebuild
19
+ from sphinx._cli.util.colour import bold
20
+ from sphinx.config import Config
22
21
  from sphinx.environment import BuildEnvironment
23
22
  from sphinx.errors import ApplicationError, ConfigError, VersionRequirementError
24
23
  from sphinx.events import EventManager
@@ -27,9 +26,8 @@ from sphinx.locale import __
27
26
  from sphinx.project import Project
28
27
  from sphinx.registry import SphinxComponentRegistry
29
28
  from sphinx.util import docutils, logging
30
- from sphinx.util._pathlib import _StrPath
29
+ from sphinx.util._pathlib import _StrPath, _StrPathProperty
31
30
  from sphinx.util.build_phase import BuildPhase
32
- from sphinx.util.console import bold
33
31
  from sphinx.util.display import progress_message
34
32
  from sphinx.util.i18n import CatalogRepository
35
33
  from sphinx.util.logging import prefixed_warnings
@@ -37,6 +35,7 @@ from sphinx.util.osutil import ensuredir, relpath
37
35
  from sphinx.util.tags import Tags
38
36
 
39
37
  if TYPE_CHECKING:
38
+ import os
40
39
  from collections.abc import Callable, Collection, Iterable, Sequence, Set
41
40
  from pathlib import Path
42
41
  from typing import IO, Any, Final, Literal
@@ -44,19 +43,28 @@ if TYPE_CHECKING:
44
43
  from docutils import nodes
45
44
  from docutils.nodes import Element, Node
46
45
  from docutils.parsers import Parser
46
+ from docutils.parsers.rst import Directive
47
47
  from docutils.transforms import Transform
48
48
  from pygments.lexer import Lexer
49
49
 
50
50
  from sphinx import addnodes
51
51
  from sphinx.builders import Builder
52
+ from sphinx.config import ENUM, _ConfigRebuild
52
53
  from sphinx.domains import Domain, Index
53
54
  from sphinx.environment.collectors import EnvironmentCollector
54
55
  from sphinx.ext.autodoc import Documenter, _AutodocProcessDocstringListener
55
56
  from sphinx.ext.todo import todo_node
56
57
  from sphinx.extension import Extension
58
+ from sphinx.registry import (
59
+ _MathsBlockRenderers,
60
+ _MathsInlineRenderers,
61
+ _NodeHandler,
62
+ _NodeHandlerPair,
63
+ )
57
64
  from sphinx.roles import XRefRole
58
65
  from sphinx.search import SearchLanguage
59
66
  from sphinx.theming import Theme
67
+ from sphinx.util.docfields import Field
60
68
  from sphinx.util.typing import RoleFunction, TitleGetter
61
69
 
62
70
 
@@ -87,6 +95,7 @@ builtin_extensions: tuple[str, ...] = (
87
95
  'sphinx.domains.rst',
88
96
  'sphinx.domains.std',
89
97
  'sphinx.directives',
98
+ 'sphinx.directives.admonitions',
90
99
  'sphinx.directives.code',
91
100
  'sphinx.directives.other',
92
101
  'sphinx.directives.patches',
@@ -141,14 +150,30 @@ class Sphinx:
141
150
  warningiserror: Final = False
142
151
  _warncount: int
143
152
 
144
- def __init__(self, srcdir: str | os.PathLike[str], confdir: str | os.PathLike[str] | None,
145
- outdir: str | os.PathLike[str], doctreedir: str | os.PathLike[str],
146
- buildername: str, confoverrides: dict | None = None,
147
- status: IO[str] | None = sys.stdout, warning: IO[str] | None = sys.stderr,
148
- freshenv: bool = False, warningiserror: bool = False,
149
- tags: Sequence[str] = (),
150
- verbosity: int = 0, parallel: int = 0, keep_going: bool = False,
151
- pdb: bool = False, exception_on_warning: bool = False) -> None:
153
+ srcdir = _StrPathProperty()
154
+ confdir = _StrPathProperty()
155
+ outdir = _StrPathProperty()
156
+ doctreedir = _StrPathProperty()
157
+
158
+ def __init__(
159
+ self,
160
+ srcdir: str | os.PathLike[str],
161
+ confdir: str | os.PathLike[str] | None,
162
+ outdir: str | os.PathLike[str],
163
+ doctreedir: str | os.PathLike[str],
164
+ buildername: str,
165
+ confoverrides: dict[str, Any] | None = None,
166
+ status: IO[str] | None = sys.stdout,
167
+ warning: IO[str] | None = sys.stderr,
168
+ freshenv: bool = False,
169
+ warningiserror: bool = False,
170
+ tags: Sequence[str] = (),
171
+ verbosity: int = 0,
172
+ parallel: int = 0,
173
+ keep_going: bool = False,
174
+ pdb: bool = False,
175
+ exception_on_warning: bool = False,
176
+ ) -> None:
152
177
  """Initialize the Sphinx application.
153
178
 
154
179
  :param srcdir: The path to the source directory.
@@ -182,17 +207,20 @@ class Sphinx:
182
207
  self.outdir = _StrPath(outdir).resolve()
183
208
  self.doctreedir = _StrPath(doctreedir).resolve()
184
209
 
185
- if not path.isdir(self.srcdir):
186
- raise ApplicationError(__('Cannot find source directory (%s)') %
187
- self.srcdir)
210
+ if not self.srcdir.is_dir():
211
+ raise ApplicationError(
212
+ __('Cannot find source directory (%s)') % self.srcdir
213
+ )
188
214
 
189
- if path.exists(self.outdir) and not path.isdir(self.outdir):
190
- raise ApplicationError(__('Output directory (%s) is not a directory') %
191
- self.outdir)
215
+ if self.outdir.exists() and not self.outdir.is_dir():
216
+ raise ApplicationError(
217
+ __('Output directory (%s) is not a directory') % self.outdir
218
+ )
192
219
 
193
220
  if self.srcdir == self.outdir:
194
- raise ApplicationError(__('Source directory and destination '
195
- 'directory cannot be identical'))
221
+ raise ApplicationError(
222
+ __('Source directory and destination directory cannot be identical')
223
+ )
196
224
 
197
225
  self.parallel = parallel
198
226
 
@@ -241,10 +269,17 @@ class Sphinx:
241
269
  self._init_i18n()
242
270
 
243
271
  # check the Sphinx version if requested
244
- if self.config.needs_sphinx and self.config.needs_sphinx > sphinx.__display_version__:
272
+ if (
273
+ self.config.needs_sphinx
274
+ and self.config.needs_sphinx > sphinx.__display_version__
275
+ ):
245
276
  raise VersionRequirementError(
246
- __('This project needs at least Sphinx v%s and therefore cannot '
247
- 'be built with this version.') % self.config.needs_sphinx)
277
+ __(
278
+ 'This project needs at least Sphinx v%s and therefore cannot '
279
+ 'be built with this version.'
280
+ )
281
+ % self.config.needs_sphinx
282
+ )
248
283
 
249
284
  # load all built-in extension modules, first-party extension modules,
250
285
  # and first-party themes
@@ -258,21 +293,23 @@ class Sphinx:
258
293
  # preload builder module (before init config values)
259
294
  self.preload_builder(buildername)
260
295
 
261
- if not path.isdir(outdir):
296
+ if not self.outdir.is_dir():
262
297
  with progress_message(__('making output directory')):
263
- ensuredir(outdir)
298
+ ensuredir(self.outdir)
264
299
 
265
300
  # the config file itself can be an extension
266
301
  if self.config.setup:
267
- prefix = __('while setting up extension %s:') % "conf.py"
302
+ prefix = __('while setting up extension %s:') % 'conf.py'
268
303
  with prefixed_warnings(prefix):
269
304
  if callable(self.config.setup):
270
305
  self.config.setup(self)
271
306
  else:
272
307
  raise ConfigError(
273
- __("'setup' as currently defined in conf.py isn't a Python callable. "
274
- "Please modify its definition to make it a callable function. "
275
- "This is needed for conf.py to behave as a Sphinx extension."),
308
+ __(
309
+ "'setup' as currently defined in conf.py isn't a Python callable. "
310
+ 'Please modify its definition to make it a callable function. '
311
+ 'This is needed for conf.py to behave as a Sphinx extension.'
312
+ ),
276
313
  )
277
314
 
278
315
  # Report any warnings for overrides.
@@ -305,30 +342,38 @@ class Sphinx:
305
342
  """Load translated strings from the configured localedirs if enabled in
306
343
  the configuration.
307
344
  """
308
- logger.info(bold(__('loading translations [%s]... ')), self.config.language,
309
- nonl=True)
345
+ logger.info(
346
+ bold(__('loading translations [%s]... ')), self.config.language, nonl=True
347
+ )
310
348
 
311
349
  # compile mo files if sphinx.po file in user locale directories are updated
312
- repo = CatalogRepository(self.srcdir, self.config.locale_dirs,
313
- self.config.language, self.config.source_encoding)
350
+ repo = CatalogRepository(
351
+ self.srcdir,
352
+ self.config.locale_dirs,
353
+ self.config.language,
354
+ self.config.source_encoding,
355
+ )
314
356
  for catalog in repo.catalogs:
315
357
  if catalog.domain == 'sphinx' and catalog.is_outdated():
316
- catalog.write_mo(self.config.language,
317
- self.config.gettext_allow_fuzzy_translations)
358
+ catalog.write_mo(
359
+ self.config.language, self.config.gettext_allow_fuzzy_translations
360
+ )
318
361
 
319
- locale_dirs: list[str | None] = list(repo.locale_dirs)
362
+ locale_dirs: list[_StrPath | None] = list(repo.locale_dirs)
320
363
  locale_dirs += [None]
321
- locale_dirs += [path.join(package_dir, 'locale')]
364
+ locale_dirs += [package_dir / 'locale']
322
365
 
323
- self.translator, has_translation = locale.init(locale_dirs, self.config.language)
366
+ self.translator, has_translation = locale.init(
367
+ locale_dirs, self.config.language
368
+ )
324
369
  if has_translation or self.config.language == 'en':
325
370
  logger.info(__('done'))
326
371
  else:
327
372
  logger.info(__('not available for built-in messages'))
328
373
 
329
374
  def _init_env(self, freshenv: bool) -> BuildEnvironment:
330
- filename = path.join(self.doctreedir, ENV_PICKLE_FILENAME)
331
- if freshenv or not os.path.exists(filename):
375
+ filename = self.doctreedir / ENV_PICKLE_FILENAME
376
+ if freshenv or not filename.exists():
332
377
  return self._create_fresh_env()
333
378
  else:
334
379
  return self._load_existing_env(filename)
@@ -339,12 +384,12 @@ class Sphinx:
339
384
  return env
340
385
 
341
386
  @progress_message(__('loading pickled environment'))
342
- def _load_existing_env(self, filename: str) -> BuildEnvironment:
387
+ def _load_existing_env(self, filename: Path) -> BuildEnvironment:
343
388
  try:
344
389
  with open(filename, 'rb') as f:
345
390
  env = pickle.load(f)
346
- env.setup(self)
347
- self._fresh_env_used = False
391
+ env.setup(self)
392
+ self._fresh_env_used = False
348
393
  except Exception as err:
349
394
  logger.info(__('failed: %s'), err)
350
395
  env = self._create_fresh_env()
@@ -370,7 +415,7 @@ class Sphinx:
370
415
 
371
416
  # ---- main "build" method -------------------------------------------------
372
417
 
373
- def build(self, force_all: bool = False, filenames: list[str] | None = None) -> None:
418
+ def build(self, force_all: bool = False, filenames: Sequence[Path] = ()) -> None:
374
419
  self.phase = BuildPhase.READING
375
420
  try:
376
421
  if force_all:
@@ -383,9 +428,9 @@ class Sphinx:
383
428
  self.events.emit('build-finished', None)
384
429
  except Exception as err:
385
430
  # delete the saved env to force a fresh build next time
386
- envfile = path.join(self.doctreedir, ENV_PICKLE_FILENAME)
387
- if path.isfile(envfile):
388
- os.unlink(envfile)
431
+ envfile = self.doctreedir / ENV_PICKLE_FILENAME
432
+ if envfile.is_file():
433
+ envfile.unlink()
389
434
  self.events.emit('build-finished', err)
390
435
  raise
391
436
 
@@ -397,8 +442,10 @@ class Sphinx:
397
442
  elif self._warncount == 1:
398
443
  if self._fail_on_warnings:
399
444
  self.statuscode = 1
400
- msg = __('build finished with problems, 1 warning '
401
- '(with warnings treated as errors).')
445
+ msg = __(
446
+ 'build finished with problems, 1 warning '
447
+ '(with warnings treated as errors).'
448
+ )
402
449
  elif self.statuscode != 0:
403
450
  msg = __('build finished with problems, 1 warning.')
404
451
  else:
@@ -407,8 +454,10 @@ class Sphinx:
407
454
  else:
408
455
  if self._fail_on_warnings:
409
456
  self.statuscode = 1
410
- msg = __('build finished with problems, %s warnings '
411
- '(with warnings treated as errors).')
457
+ msg = __(
458
+ 'build finished with problems, %s warnings '
459
+ '(with warnings treated as errors).'
460
+ )
412
461
  elif self.statuscode != 0:
413
462
  msg = __('build finished with problems, %s warnings.')
414
463
  else:
@@ -417,10 +466,13 @@ class Sphinx:
417
466
 
418
467
  if self.statuscode == 0 and self.builder.epilog:
419
468
  logger.info('')
420
- logger.info(self.builder.epilog, {
421
- 'outdir': relpath(self.outdir),
422
- 'project': self.config.project,
423
- })
469
+ logger.info(
470
+ self.builder.epilog,
471
+ {
472
+ 'outdir': relpath(self.outdir),
473
+ 'project': self.config.project,
474
+ },
475
+ )
424
476
 
425
477
  self.builder.cleanup()
426
478
 
@@ -465,18 +517,16 @@ class Sphinx:
465
517
  self,
466
518
  event: Literal['config-inited'],
467
519
  callback: Callable[[Sphinx, Config], None],
468
- priority: int = 500
469
- ) -> int:
470
- ...
520
+ priority: int = 500,
521
+ ) -> int: ...
471
522
 
472
523
  @overload
473
524
  def connect(
474
525
  self,
475
526
  event: Literal['builder-inited'],
476
527
  callback: Callable[[Sphinx], None],
477
- priority: int = 500
478
- ) -> int:
479
- ...
528
+ priority: int = 500,
529
+ ) -> int: ...
480
530
 
481
531
  @overload
482
532
  def connect(
@@ -485,110 +535,98 @@ class Sphinx:
485
535
  callback: Callable[
486
536
  [Sphinx, BuildEnvironment, Set[str], Set[str], Set[str]], Sequence[str]
487
537
  ],
488
- priority: int = 500
489
- ) -> int:
490
- ...
538
+ priority: int = 500,
539
+ ) -> int: ...
491
540
 
492
541
  @overload
493
542
  def connect(
494
543
  self,
495
544
  event: Literal['env-before-read-docs'],
496
545
  callback: Callable[[Sphinx, BuildEnvironment, list[str]], None],
497
- priority: int = 500
498
- ) -> int:
499
- ...
546
+ priority: int = 500,
547
+ ) -> int: ...
500
548
 
501
549
  @overload
502
550
  def connect(
503
551
  self,
504
552
  event: Literal['env-purge-doc'],
505
553
  callback: Callable[[Sphinx, BuildEnvironment, str], None],
506
- priority: int = 500
507
- ) -> int:
508
- ...
554
+ priority: int = 500,
555
+ ) -> int: ...
509
556
 
510
557
  @overload
511
558
  def connect(
512
559
  self,
513
560
  event: Literal['source-read'],
514
561
  callback: Callable[[Sphinx, str, list[str]], None],
515
- priority: int = 500
516
- ) -> int:
517
- ...
562
+ priority: int = 500,
563
+ ) -> int: ...
518
564
 
519
565
  @overload
520
566
  def connect(
521
567
  self,
522
568
  event: Literal['include-read'],
523
569
  callback: Callable[[Sphinx, Path, str, list[str]], None],
524
- priority: int = 500
525
- ) -> int:
526
- ...
570
+ priority: int = 500,
571
+ ) -> int: ...
527
572
 
528
573
  @overload
529
574
  def connect(
530
575
  self,
531
576
  event: Literal['doctree-read'],
532
577
  callback: Callable[[Sphinx, nodes.document], None],
533
- priority: int = 500
534
- ) -> int:
535
- ...
578
+ priority: int = 500,
579
+ ) -> int: ...
536
580
 
537
581
  @overload
538
582
  def connect(
539
583
  self,
540
584
  event: Literal['env-merge-info'],
541
585
  callback: Callable[
542
- [Sphinx, BuildEnvironment, list[str], BuildEnvironment], None
586
+ [Sphinx, BuildEnvironment, Set[str], BuildEnvironment], None
543
587
  ],
544
- priority: int = 500
545
- ) -> int:
546
- ...
588
+ priority: int = 500,
589
+ ) -> int: ...
547
590
 
548
591
  @overload
549
592
  def connect(
550
593
  self,
551
594
  event: Literal['env-updated'],
552
595
  callback: Callable[[Sphinx, BuildEnvironment], str],
553
- priority: int = 500
554
- ) -> int:
555
- ...
596
+ priority: int = 500,
597
+ ) -> int: ...
556
598
 
557
599
  @overload
558
600
  def connect(
559
601
  self,
560
602
  event: Literal['env-get-updated'],
561
603
  callback: Callable[[Sphinx, BuildEnvironment], Iterable[str]],
562
- priority: int = 500
563
- ) -> int:
564
- ...
604
+ priority: int = 500,
605
+ ) -> int: ...
565
606
 
566
607
  @overload
567
608
  def connect(
568
609
  self,
569
610
  event: Literal['env-check-consistency'],
570
611
  callback: Callable[[Sphinx, BuildEnvironment], None],
571
- priority: int = 500
572
- ) -> int:
573
- ...
612
+ priority: int = 500,
613
+ ) -> int: ...
574
614
 
575
615
  @overload
576
616
  def connect(
577
617
  self,
578
618
  event: Literal['write-started'],
579
619
  callback: Callable[[Sphinx, Builder], None],
580
- priority: int = 500
581
- ) -> int:
582
- ...
620
+ priority: int = 500,
621
+ ) -> int: ...
583
622
 
584
623
  @overload
585
624
  def connect(
586
625
  self,
587
626
  event: Literal['doctree-resolved'],
588
627
  callback: Callable[[Sphinx, nodes.document, str], None],
589
- priority: int = 500
590
- ) -> int:
591
- ...
628
+ priority: int = 500,
629
+ ) -> int: ...
592
630
 
593
631
  @overload
594
632
  def connect(
@@ -598,27 +636,24 @@ class Sphinx:
598
636
  [Sphinx, BuildEnvironment, addnodes.pending_xref, nodes.TextElement],
599
637
  nodes.reference | None,
600
638
  ],
601
- priority: int = 500
602
- ) -> int:
603
- ...
639
+ priority: int = 500,
640
+ ) -> int: ...
604
641
 
605
642
  @overload
606
643
  def connect(
607
644
  self,
608
645
  event: Literal['warn-missing-reference'],
609
646
  callback: Callable[[Sphinx, Domain, addnodes.pending_xref], bool | None],
610
- priority: int = 500
611
- ) -> int:
612
- ...
647
+ priority: int = 500,
648
+ ) -> int: ...
613
649
 
614
650
  @overload
615
651
  def connect(
616
652
  self,
617
653
  event: Literal['build-finished'],
618
654
  callback: Callable[[Sphinx, Exception | None], None],
619
- priority: int = 500
620
- ) -> int:
621
- ...
655
+ priority: int = 500,
656
+ ) -> int: ...
622
657
 
623
658
  # ---- Events from builtin builders --------------------------------------
624
659
 
@@ -627,9 +662,8 @@ class Sphinx:
627
662
  self,
628
663
  event: Literal['html-collect-pages'],
629
664
  callback: Callable[[Sphinx], Iterable[tuple[str, dict[str, Any], str]]],
630
- priority: int = 500
631
- ) -> int:
632
- ...
665
+ priority: int = 500,
666
+ ) -> int: ...
633
667
 
634
668
  @overload
635
669
  def connect(
@@ -638,18 +672,16 @@ class Sphinx:
638
672
  callback: Callable[
639
673
  [Sphinx, str, str, dict[str, Any], nodes.document], str | None
640
674
  ],
641
- priority: int = 500
642
- ) -> int:
643
- ...
675
+ priority: int = 500,
676
+ ) -> int: ...
644
677
 
645
678
  @overload
646
679
  def connect(
647
680
  self,
648
681
  event: Literal['linkcheck-process-uri'],
649
682
  callback: Callable[[Sphinx, str], str | None],
650
- priority: int = 500
651
- ) -> int:
652
- ...
683
+ priority: int = 500,
684
+ ) -> int: ...
653
685
 
654
686
  # ---- Events from builtin extensions-- ----------------------------------
655
687
 
@@ -658,9 +690,8 @@ class Sphinx:
658
690
  self,
659
691
  event: Literal['object-description-transform'],
660
692
  callback: Callable[[Sphinx, str, str, addnodes.desc_content], None],
661
- priority: int = 500
662
- ) -> int:
663
- ...
693
+ priority: int = 500,
694
+ ) -> int: ...
664
695
 
665
696
  # ---- Events from first-party extensions --------------------------------
666
697
 
@@ -669,18 +700,16 @@ class Sphinx:
669
700
  self,
670
701
  event: Literal['autodoc-process-docstring'],
671
702
  callback: _AutodocProcessDocstringListener,
672
- priority: int = 500
673
- ) -> int:
674
- ...
703
+ priority: int = 500,
704
+ ) -> int: ...
675
705
 
676
706
  @overload
677
707
  def connect(
678
708
  self,
679
709
  event: Literal['autodoc-before-process-signature'],
680
710
  callback: Callable[[Sphinx, Any, bool], None],
681
- priority: int = 500
682
- ) -> int:
683
- ...
711
+ priority: int = 500,
712
+ ) -> int: ...
684
713
 
685
714
  @overload
686
715
  def connect(
@@ -689,7 +718,9 @@ class Sphinx:
689
718
  callback: Callable[
690
719
  [
691
720
  Sphinx,
692
- Literal['module', 'class', 'exception', 'function', 'method', 'attribute'],
721
+ Literal[
722
+ 'module', 'class', 'exception', 'function', 'method', 'attribute'
723
+ ],
693
724
  str,
694
725
  Any,
695
726
  dict[str, bool],
@@ -698,18 +729,16 @@ class Sphinx:
698
729
  ],
699
730
  tuple[str | None, str | None] | None,
700
731
  ],
701
- priority: int = 500
702
- ) -> int:
703
- ...
732
+ priority: int = 500,
733
+ ) -> int: ...
704
734
 
705
735
  @overload
706
736
  def connect(
707
737
  self,
708
738
  event: Literal['autodoc-process-bases'],
709
739
  callback: Callable[[Sphinx, str, Any, dict[str, bool], list[str]], None],
710
- priority: int = 500
711
- ) -> int:
712
- ...
740
+ priority: int = 500,
741
+ ) -> int: ...
713
742
 
714
743
  @overload
715
744
  def connect(
@@ -718,7 +747,9 @@ class Sphinx:
718
747
  callback: Callable[
719
748
  [
720
749
  Sphinx,
721
- Literal['module', 'class', 'exception', 'function', 'method', 'attribute'],
750
+ Literal[
751
+ 'module', 'class', 'exception', 'function', 'method', 'attribute'
752
+ ],
722
753
  str,
723
754
  Any,
724
755
  bool,
@@ -726,9 +757,8 @@ class Sphinx:
726
757
  ],
727
758
  bool,
728
759
  ],
729
- priority: int = 500
730
- ) -> int:
731
- ...
760
+ priority: int = 500,
761
+ ) -> int: ...
732
762
 
733
763
  @overload
734
764
  def connect(
@@ -736,8 +766,7 @@ class Sphinx:
736
766
  event: Literal['todo-defined'],
737
767
  callback: Callable[[Sphinx, todo_node], None],
738
768
  priority: int = 500,
739
- ) -> int:
740
- ...
769
+ ) -> int: ...
741
770
 
742
771
  @overload
743
772
  def connect(
@@ -748,8 +777,7 @@ class Sphinx:
748
777
  tuple[str, dict[str, tuple[Literal['class', 'def', 'other'], int, int]]],
749
778
  ],
750
779
  priority: int = 500,
751
- ) -> int:
752
- ...
780
+ ) -> int: ...
753
781
 
754
782
  @overload
755
783
  def connect(
@@ -757,8 +785,7 @@ class Sphinx:
757
785
  event: Literal['viewcode-follow-imported'],
758
786
  callback: Callable[[Sphinx, str, str], str | None],
759
787
  priority: int = 500,
760
- ) -> int:
761
- ...
788
+ ) -> int: ...
762
789
 
763
790
  # ---- Catch-all ---------------------------------------------------------
764
791
 
@@ -767,12 +794,13 @@ class Sphinx:
767
794
  self,
768
795
  event: str,
769
796
  callback: Callable[..., Any],
770
- priority: int = 500
771
- ) -> int:
772
- ...
797
+ priority: int = 500,
798
+ ) -> int: ...
773
799
 
774
800
  # event interface
775
- def connect(self, event: str, callback: Callable, priority: int = 500) -> int:
801
+ def connect(
802
+ self, event: str, callback: Callable[..., Any], priority: int = 500
803
+ ) -> int:
776
804
  """Register *callback* to be called when *event* is emitted.
777
805
 
778
806
  For details on available core events and the arguments of callback
@@ -789,8 +817,13 @@ class Sphinx:
789
817
  Support *priority*
790
818
  """
791
819
  listener_id = self.events.connect(event, callback, priority)
792
- logger.debug('[app] connecting event %r (%d): %r [id=%s]',
793
- event, priority, callback, listener_id)
820
+ logger.debug(
821
+ '[app] connecting event %r (%d): %r [id=%s]',
822
+ event,
823
+ priority,
824
+ callback,
825
+ listener_id,
826
+ )
794
827
  return listener_id
795
828
 
796
829
  def disconnect(self, listener_id: int) -> None:
@@ -801,8 +834,12 @@ class Sphinx:
801
834
  logger.debug('[app] disconnecting event: [id=%s]', listener_id)
802
835
  self.events.disconnect(listener_id)
803
836
 
804
- def emit(self, event: str, *args: Any,
805
- allowed_exceptions: tuple[type[Exception], ...] = ()) -> list:
837
+ def emit(
838
+ self,
839
+ event: str,
840
+ *args: Any,
841
+ allowed_exceptions: tuple[type[Exception], ...] = (),
842
+ ) -> list[Any]:
806
843
  """Emit *event* and pass *arguments* to the callback functions.
807
844
 
808
845
  Return the return values of all callbacks as a list. Do not emit core
@@ -818,8 +855,12 @@ class Sphinx:
818
855
  """
819
856
  return self.events.emit(event, *args, allowed_exceptions=allowed_exceptions)
820
857
 
821
- def emit_firstresult(self, event: str, *args: Any,
822
- allowed_exceptions: tuple[type[Exception], ...] = ()) -> Any:
858
+ def emit_firstresult(
859
+ self,
860
+ event: str,
861
+ *args: Any,
862
+ allowed_exceptions: tuple[type[Exception], ...] = (),
863
+ ) -> Any:
823
864
  """Emit *event* and pass *arguments* to the callback functions.
824
865
 
825
866
  Return the result of the first callback that doesn't return ``None``.
@@ -833,8 +874,9 @@ class Sphinx:
833
874
 
834
875
  Added *allowed_exceptions* to specify path-through exceptions
835
876
  """
836
- return self.events.emit_firstresult(event, *args,
837
- allowed_exceptions=allowed_exceptions)
877
+ return self.events.emit_firstresult(
878
+ event, *args, allowed_exceptions=allowed_exceptions
879
+ )
838
880
 
839
881
  # registering addon parts
840
882
 
@@ -851,7 +893,10 @@ class Sphinx:
851
893
  self.registry.add_builder(builder, override=override)
852
894
 
853
895
  def add_config_value(
854
- self, name: str, default: Any, rebuild: _ConfigRebuild,
896
+ self,
897
+ name: str,
898
+ default: Any,
899
+ rebuild: _ConfigRebuild,
855
900
  types: type | Collection[type] | ENUM = (),
856
901
  description: str = '',
857
902
  ) -> None:
@@ -892,7 +937,13 @@ class Sphinx:
892
937
  The *description* parameter.
893
938
  """
894
939
  logger.debug('[app] adding config value: %r', (name, default, rebuild, types))
895
- self.config.add(name, default, rebuild, types, description)
940
+ self.config.add(
941
+ name=name,
942
+ default=default,
943
+ rebuild=rebuild,
944
+ types=types,
945
+ description=description,
946
+ )
896
947
 
897
948
  def add_event(self, name: str) -> None:
898
949
  """Register an event called *name*.
@@ -904,8 +955,12 @@ class Sphinx:
904
955
  logger.debug('[app] adding event: %r', name)
905
956
  self.events.add(name)
906
957
 
907
- def set_translator(self, name: str, translator_class: type[nodes.NodeVisitor],
908
- override: bool = False) -> None:
958
+ def set_translator(
959
+ self,
960
+ name: str,
961
+ translator_class: type[nodes.NodeVisitor],
962
+ override: bool = False,
963
+ ) -> None:
909
964
  """Register or override a Docutils translator class.
910
965
 
911
966
  This is used to register a custom output translator or to replace a
@@ -923,8 +978,12 @@ class Sphinx:
923
978
  """
924
979
  self.registry.add_translator(name, translator_class, override=override)
925
980
 
926
- def add_node(self, node: type[Element], override: bool = False,
927
- **kwargs: tuple[Callable, Callable | None]) -> None:
981
+ def add_node(
982
+ self,
983
+ node: type[Element],
984
+ override: bool = False,
985
+ **kwargs: _NodeHandlerPair,
986
+ ) -> None:
928
987
  """Register a Docutils node class.
929
988
 
930
989
  This is necessary for Docutils internals. It may also be used in the
@@ -944,10 +1003,11 @@ class Sphinx:
944
1003
 
945
1004
  .. code-block:: python
946
1005
 
947
- class math(docutils.nodes.Element): pass
1006
+ class math(docutils.nodes.Element): ...
948
1007
 
949
1008
  def visit_math_html(self, node):
950
1009
  self.body.append(self.starttag(node, 'math'))
1010
+
951
1011
  def depart_math_html(self, node):
952
1012
  self.body.append('</math>')
953
1013
 
@@ -961,15 +1021,26 @@ class Sphinx:
961
1021
  """
962
1022
  logger.debug('[app] adding node: %r', (node, kwargs))
963
1023
  if not override and docutils.is_node_registered(node):
964
- logger.warning(__('node class %r is already registered, '
965
- 'its visitors will be overridden'),
966
- node.__name__, type='app', subtype='add_node')
1024
+ logger.warning(
1025
+ __(
1026
+ 'node class %r is already registered, '
1027
+ 'its visitors will be overridden'
1028
+ ),
1029
+ node.__name__,
1030
+ type='app',
1031
+ subtype='add_node',
1032
+ )
967
1033
  docutils.register_node(node)
968
1034
  self.registry.add_translation_handlers(node, **kwargs)
969
1035
 
970
- def add_enumerable_node(self, node: type[Element], figtype: str,
971
- title_getter: TitleGetter | None = None, override: bool = False,
972
- **kwargs: tuple[Callable, Callable]) -> None:
1036
+ def add_enumerable_node(
1037
+ self,
1038
+ node: type[Element],
1039
+ figtype: str,
1040
+ title_getter: TitleGetter | None = None,
1041
+ override: bool = False,
1042
+ **kwargs: tuple[_NodeHandler, _NodeHandler],
1043
+ ) -> None:
973
1044
  """Register a Docutils node class as a numfig target.
974
1045
 
975
1046
  Sphinx numbers the node automatically. And then the users can refer it
@@ -993,10 +1064,14 @@ class Sphinx:
993
1064
 
994
1065
  .. versionadded:: 1.4
995
1066
  """
996
- self.registry.add_enumerable_node(node, figtype, title_getter, override=override)
1067
+ self.registry.add_enumerable_node(
1068
+ node, figtype, title_getter, override=override
1069
+ )
997
1070
  self.add_node(node, override=override, **kwargs)
998
1071
 
999
- def add_directive(self, name: str, cls: type[Directive], override: bool = False) -> None:
1072
+ def add_directive(
1073
+ self, name: str, cls: type[Directive], override: bool = False
1074
+ ) -> None:
1000
1075
  """Register a Docutils directive.
1001
1076
 
1002
1077
  :param name: The name of the directive
@@ -1023,7 +1098,7 @@ class Sphinx:
1023
1098
  }
1024
1099
 
1025
1100
  def run(self):
1026
- ...
1101
+ pass
1027
1102
 
1028
1103
  def setup(app):
1029
1104
  app.add_directive('my-directive', MyDirective)
@@ -1040,8 +1115,12 @@ class Sphinx:
1040
1115
  """
1041
1116
  logger.debug('[app] adding directive: %r', (name, cls))
1042
1117
  if not override and docutils.is_directive_registered(name):
1043
- logger.warning(__('directive %r is already registered, it will be overridden'),
1044
- name, type='app', subtype='add_directive')
1118
+ logger.warning(
1119
+ __('directive %r is already registered and will not be overridden'),
1120
+ name,
1121
+ type='app',
1122
+ subtype='add_directive',
1123
+ )
1045
1124
 
1046
1125
  docutils.register_directive(name, cls)
1047
1126
 
@@ -1062,13 +1141,16 @@ class Sphinx:
1062
1141
  """
1063
1142
  logger.debug('[app] adding role: %r', (name, role))
1064
1143
  if not override and docutils.is_role_registered(name):
1065
- logger.warning(__('role %r is already registered, it will be overridden'),
1066
- name, type='app', subtype='add_role')
1144
+ logger.warning(
1145
+ __('role %r is already registered and will not be overridden'),
1146
+ name,
1147
+ type='app',
1148
+ subtype='add_role',
1149
+ )
1067
1150
  docutils.register_role(name, role)
1068
1151
 
1069
1152
  def add_generic_role(
1070
1153
  self, name: str, nodeclass: type[Node], override: bool = False
1071
-
1072
1154
  ) -> None:
1073
1155
  """Register a generic Docutils role.
1074
1156
 
@@ -1087,8 +1169,12 @@ class Sphinx:
1087
1169
  # ``register_canonical_role``.
1088
1170
  logger.debug('[app] adding generic role: %r', (name, nodeclass))
1089
1171
  if not override and docutils.is_role_registered(name):
1090
- logger.warning(__('role %r is already registered, it will be overridden'),
1091
- name, type='app', subtype='add_generic_role')
1172
+ logger.warning(
1173
+ __('role %r is already registered and will not be overridden'),
1174
+ name,
1175
+ type='app',
1176
+ subtype='add_generic_role',
1177
+ )
1092
1178
  role = roles.GenericRole(name, nodeclass)
1093
1179
  docutils.register_role(name, role)
1094
1180
 
@@ -1106,8 +1192,9 @@ class Sphinx:
1106
1192
  """
1107
1193
  self.registry.add_domain(domain, override=override)
1108
1194
 
1109
- def add_directive_to_domain(self, domain: str, name: str,
1110
- cls: type[Directive], override: bool = False) -> None:
1195
+ def add_directive_to_domain(
1196
+ self, domain: str, name: str, cls: type[Directive], override: bool = False
1197
+ ) -> None:
1111
1198
  """Register a Docutils directive in a domain.
1112
1199
 
1113
1200
  Like :meth:`add_directive`, but the directive is added to the domain
@@ -1126,8 +1213,13 @@ class Sphinx:
1126
1213
  """
1127
1214
  self.registry.add_directive_to_domain(domain, name, cls, override=override)
1128
1215
 
1129
- def add_role_to_domain(self, domain: str, name: str, role: RoleFunction | XRefRole,
1130
- override: bool = False) -> None:
1216
+ def add_role_to_domain(
1217
+ self,
1218
+ domain: str,
1219
+ name: str,
1220
+ role: RoleFunction | XRefRole,
1221
+ override: bool = False,
1222
+ ) -> None:
1131
1223
  """Register a Docutils role in a domain.
1132
1224
 
1133
1225
  Like :meth:`add_role`, but the role is added to the domain named
@@ -1146,8 +1238,9 @@ class Sphinx:
1146
1238
  """
1147
1239
  self.registry.add_role_to_domain(domain, name, role, override=override)
1148
1240
 
1149
- def add_index_to_domain(self, domain: str, index: type[Index], _override: bool = False,
1150
- ) -> None:
1241
+ def add_index_to_domain(
1242
+ self, domain: str, index: type[Index], _override: bool = False
1243
+ ) -> None:
1151
1244
  """Register a custom index for a domain.
1152
1245
 
1153
1246
  Add a custom *index* class to the domain named *domain*.
@@ -1164,12 +1257,18 @@ class Sphinx:
1164
1257
  """
1165
1258
  self.registry.add_index_to_domain(domain, index)
1166
1259
 
1167
- def add_object_type(self, directivename: str, rolename: str, indextemplate: str = '',
1168
- parse_node: Callable | None = None,
1169
- ref_nodeclass: type[nodes.TextElement] | None = None,
1170
- objname: str = '', doc_field_types: Sequence = (),
1171
- override: bool = False,
1172
- ) -> None:
1260
+ def add_object_type(
1261
+ self,
1262
+ directivename: str,
1263
+ rolename: str,
1264
+ indextemplate: str = '',
1265
+ parse_node: Callable[[BuildEnvironment, str, addnodes.desc_signature], str]
1266
+ | None = None,
1267
+ ref_nodeclass: type[nodes.TextElement] | None = None,
1268
+ objname: str = '',
1269
+ doc_field_types: Sequence[Field] = (),
1270
+ override: bool = False,
1271
+ ) -> None:
1173
1272
  """Register a new object type.
1174
1273
 
1175
1274
  This method is a very convenient way to add a new :term:`object` type
@@ -1229,13 +1328,24 @@ class Sphinx:
1229
1328
  .. versionchanged:: 1.8
1230
1329
  Add *override* keyword.
1231
1330
  """
1232
- self.registry.add_object_type(directivename, rolename, indextemplate, parse_node,
1233
- ref_nodeclass, objname, doc_field_types,
1234
- override=override)
1331
+ self.registry.add_object_type(
1332
+ directivename,
1333
+ rolename,
1334
+ indextemplate,
1335
+ parse_node,
1336
+ ref_nodeclass,
1337
+ objname,
1338
+ doc_field_types,
1339
+ override=override,
1340
+ )
1235
1341
 
1236
1342
  def add_crossref_type(
1237
- self, directivename: str, rolename: str, indextemplate: str = '',
1238
- ref_nodeclass: type[nodes.TextElement] | None = None, objname: str = '',
1343
+ self,
1344
+ directivename: str,
1345
+ rolename: str,
1346
+ indextemplate: str = '',
1347
+ ref_nodeclass: type[nodes.TextElement] | None = None,
1348
+ objname: str = '',
1239
1349
  override: bool = False,
1240
1350
  ) -> None:
1241
1351
  """Register a new crossref object type.
@@ -1247,8 +1357,9 @@ class Sphinx:
1247
1357
  to them using custom roles instead of generic ones (like
1248
1358
  :rst:role:`ref`). Example call::
1249
1359
 
1250
- app.add_crossref_type('topic', 'topic', 'single: %s',
1251
- docutils.nodes.emphasis)
1360
+ app.add_crossref_type(
1361
+ 'topic', 'topic', 'single: %s', docutils.nodes.emphasis
1362
+ )
1252
1363
 
1253
1364
  Example usage::
1254
1365
 
@@ -1272,9 +1383,14 @@ class Sphinx:
1272
1383
  .. versionchanged:: 1.8
1273
1384
  Add *override* keyword.
1274
1385
  """
1275
- self.registry.add_crossref_type(directivename, rolename,
1276
- indextemplate, ref_nodeclass, objname,
1277
- override=override)
1386
+ self.registry.add_crossref_type(
1387
+ directivename,
1388
+ rolename,
1389
+ indextemplate,
1390
+ ref_nodeclass,
1391
+ objname,
1392
+ override=override,
1393
+ )
1278
1394
 
1279
1395
  def add_transform(self, transform: type[Transform]) -> None:
1280
1396
  """Register a Docutils transform to be applied after parsing.
@@ -1308,7 +1424,7 @@ class Sphinx:
1308
1424
  refs: `Transform Priority Range Categories`__
1309
1425
 
1310
1426
  __ https://docutils.sourceforge.io/docs/ref/transforms.html#transform-priority-range-categories
1311
- """ # NoQA: E501,RUF100 # Flake8 thinks the URL is too long, Ruff special cases URLs.
1427
+ """
1312
1428
  self.registry.add_transform(transform)
1313
1429
 
1314
1430
  def add_post_transform(self, transform: type[Transform]) -> None:
@@ -1322,8 +1438,13 @@ class Sphinx:
1322
1438
  """
1323
1439
  self.registry.add_post_transform(transform)
1324
1440
 
1325
- def add_js_file(self, filename: str | None, priority: int = 500,
1326
- loading_method: str | None = None, **kwargs: Any) -> None:
1441
+ def add_js_file(
1442
+ self,
1443
+ filename: str | None,
1444
+ priority: int = 500,
1445
+ loading_method: str | None = None,
1446
+ **kwargs: Any,
1447
+ ) -> None:
1327
1448
  """Register a JavaScript file to include in the HTML output.
1328
1449
 
1329
1450
  :param filename: The name of a JavaScript file that the default HTML
@@ -1348,7 +1469,7 @@ class Sphinx:
1348
1469
  app.add_js_file('example.js')
1349
1470
  # => <script src="_static/example.js"></script>
1350
1471
 
1351
- app.add_js_file('example.js', loading_method="async")
1472
+ app.add_js_file('example.js', loading_method='async')
1352
1473
  # => <script src="_static/example.js" async="async"></script>
1353
1474
 
1354
1475
  app.add_js_file(None, body="var myVariable = 'foo';")
@@ -1389,7 +1510,7 @@ class Sphinx:
1389
1510
  self.registry.add_js_file(filename, priority=priority, **kwargs)
1390
1511
  with contextlib.suppress(AttributeError):
1391
1512
  self.builder.add_js_file( # type: ignore[attr-defined]
1392
- filename, priority=priority, **kwargs,
1513
+ filename, priority=priority, **kwargs
1393
1514
  )
1394
1515
 
1395
1516
  def add_css_file(self, filename: str, priority: int = 500, **kwargs: Any) -> None:
@@ -1453,11 +1574,12 @@ class Sphinx:
1453
1574
  self.registry.add_css_files(filename, priority=priority, **kwargs)
1454
1575
  with contextlib.suppress(AttributeError):
1455
1576
  self.builder.add_css_file( # type: ignore[attr-defined]
1456
- filename, priority=priority, **kwargs,
1577
+ filename, priority=priority, **kwargs
1457
1578
  )
1458
1579
 
1459
- def add_latex_package(self, packagename: str, options: str | None = None,
1460
- after_hyperref: bool = False) -> None:
1580
+ def add_latex_package(
1581
+ self, packagename: str, options: str | None = None, after_hyperref: bool = False
1582
+ ) -> None:
1461
1583
  r"""Register a package to include in the LaTeX source code.
1462
1584
 
1463
1585
  Add *packagename* to the list of packages that LaTeX source code will
@@ -1513,11 +1635,13 @@ class Sphinx:
1513
1635
  """
1514
1636
  logger.debug('[app] adding autodocumenter: %r', cls)
1515
1637
  from sphinx.ext.autodoc.directive import AutodocDirective
1638
+
1516
1639
  self.registry.add_documenter(cls.objtype, cls)
1517
1640
  self.add_directive('auto' + cls.objtype, AutodocDirective, override=override)
1518
1641
 
1519
- def add_autodoc_attrgetter(self, typ: type, getter: Callable[[Any, str, Any], Any],
1520
- ) -> None:
1642
+ def add_autodoc_attrgetter(
1643
+ self, typ: type, getter: Callable[[Any, str, Any], Any]
1644
+ ) -> None:
1521
1645
  """Register a new ``getattr``-like function for the autodoc extension.
1522
1646
 
1523
1647
  Add *getter*, which must be a function with an interface compatible to
@@ -1544,9 +1668,12 @@ class Sphinx:
1544
1668
  """
1545
1669
  logger.debug('[app] adding search language: %r', cls)
1546
1670
  from sphinx.search import languages
1671
+
1547
1672
  languages[cls.lang] = cls
1548
1673
 
1549
- def add_source_suffix(self, suffix: str, filetype: str, override: bool = False) -> None:
1674
+ def add_source_suffix(
1675
+ self, suffix: str, filetype: str, override: bool = False
1676
+ ) -> None:
1550
1677
  """Register a suffix of source files.
1551
1678
 
1552
1679
  Same as :confval:`source_suffix`. The users can override this
@@ -1586,7 +1713,7 @@ class Sphinx:
1586
1713
  logger.debug('[app] adding environment collector: %r', collector)
1587
1714
  collector().enable(self)
1588
1715
 
1589
- def add_html_theme(self, name: str, theme_path: str) -> None:
1716
+ def add_html_theme(self, name: str, theme_path: str | os.PathLike[str]) -> None:
1590
1717
  """Register a HTML Theme.
1591
1718
 
1592
1719
  The *name* is a name of theme, and *theme_path* is a full path to the
@@ -1600,8 +1727,8 @@ class Sphinx:
1600
1727
  def add_html_math_renderer(
1601
1728
  self,
1602
1729
  name: str,
1603
- inline_renderers: tuple[Callable, Callable | None] | None = None,
1604
- block_renderers: tuple[Callable, Callable | None] | None = None,
1730
+ inline_renderers: _MathsInlineRenderers | None = None,
1731
+ block_renderers: _MathsBlockRenderers | None = None,
1605
1732
  ) -> None:
1606
1733
  """Register a math renderer for HTML.
1607
1734
 
@@ -1616,7 +1743,9 @@ class Sphinx:
1616
1743
  """
1617
1744
  self.registry.add_html_math_renderer(name, inline_renderers, block_renderers)
1618
1745
 
1619
- def add_message_catalog(self, catalog: str, locale_dir: str) -> None:
1746
+ def add_message_catalog(
1747
+ self, catalog: str, locale_dir: str | os.PathLike[str]
1748
+ ) -> None:
1620
1749
  """Register a message catalog.
1621
1750
 
1622
1751
  :param catalog: The name of the catalog
@@ -1637,18 +1766,22 @@ class Sphinx:
1637
1766
  """
1638
1767
  if typ == 'read':
1639
1768
  attrname = 'parallel_read_safe'
1640
- message_not_declared = __("the %s extension does not declare if it "
1641
- "is safe for parallel reading, assuming "
1642
- "it isn't - please ask the extension author "
1643
- "to check and make it explicit")
1644
- message_not_safe = __("the %s extension is not safe for parallel reading")
1769
+ message_not_declared = __(
1770
+ 'the %s extension does not declare if it '
1771
+ 'is safe for parallel reading, assuming '
1772
+ "it isn't - please ask the extension author "
1773
+ 'to check and make it explicit'
1774
+ )
1775
+ message_not_safe = __('the %s extension is not safe for parallel reading')
1645
1776
  elif typ == 'write':
1646
1777
  attrname = 'parallel_write_safe'
1647
- message_not_declared = __("the %s extension does not declare if it "
1648
- "is safe for parallel writing, assuming "
1649
- "it isn't - please ask the extension author "
1650
- "to check and make it explicit")
1651
- message_not_safe = __("the %s extension is not safe for parallel writing")
1778
+ message_not_declared = __(
1779
+ 'the %s extension does not declare if it '
1780
+ 'is safe for parallel writing, assuming '
1781
+ "it isn't - please ask the extension author "
1782
+ 'to check and make it explicit'
1783
+ )
1784
+ message_not_safe = __('the %s extension is not safe for parallel writing')
1652
1785
  else:
1653
1786
  raise ValueError('parallel type %s is not supported' % typ)
1654
1787
 
@@ -1673,14 +1806,13 @@ class Sphinx:
1673
1806
 
1674
1807
  .. versionadded: 4.1
1675
1808
  """
1676
- if policy not in ('always', 'per_page'):
1809
+ if policy not in {'always', 'per_page'}:
1677
1810
  raise ValueError('policy %s is not supported' % policy)
1678
1811
  self.registry.html_assets_policy = policy
1679
1812
 
1680
1813
 
1681
1814
  class TemplateBridge:
1682
- """
1683
- This class defines the interface for a "template bridge", that is, a class
1815
+ """This class defines the interface for a "template bridge", that is, a class
1684
1816
  that renders templates given a template name and a context.
1685
1817
  """
1686
1818
 
@@ -1715,7 +1847,7 @@ class TemplateBridge:
1715
1847
  msg = 'must be implemented in subclasses'
1716
1848
  raise NotImplementedError(msg)
1717
1849
 
1718
- def render_string(self, template: str, context: dict) -> str:
1850
+ def render_string(self, template: str, context: dict[str, Any]) -> str:
1719
1851
  """Called by the builder to render a template given as a string with a
1720
1852
  specified context (a Python dictionary).
1721
1853
  """