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
@@ -3,22 +3,25 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import re
6
- from typing import TYPE_CHECKING, ClassVar, Generic, TypeVar, cast
6
+ from typing import TYPE_CHECKING, Generic, TypeVar, cast
7
7
 
8
8
  from docutils import nodes
9
9
  from docutils.parsers.rst import directives, roles
10
10
 
11
11
  from sphinx import addnodes
12
- from sphinx.addnodes import desc_signature # NoQA: TCH001
13
12
  from sphinx.util import docutils
14
- from sphinx.util.docfields import DocFieldTransformer, Field, TypedField
13
+ from sphinx.util.docfields import DocFieldTransformer
15
14
  from sphinx.util.docutils import SphinxDirective
16
- from sphinx.util.typing import ExtensionMetadata, OptionSpec # NoQA: TCH001
17
15
 
18
16
  if TYPE_CHECKING:
17
+ from typing import ClassVar
18
+
19
19
  from docutils.nodes import Node
20
20
 
21
+ from sphinx.addnodes import desc_signature
21
22
  from sphinx.application import Sphinx
23
+ from sphinx.util.docfields import Field, TypedField
24
+ from sphinx.util.typing import ExtensionMetadata, OptionSpec
22
25
 
23
26
 
24
27
  # RE to strip backslash escapes
@@ -27,9 +30,7 @@ strip_backslash_re = re.compile(r'\\(.)')
27
30
 
28
31
 
29
32
  def optional_int(argument: str) -> int | None:
30
- """
31
- Check for an integer argument or None value; raise ``ValueError`` if not.
32
- """
33
+ """Check for an integer argument or None value; raise ``ValueError`` if not."""
33
34
  if argument is None:
34
35
  return None
35
36
  else:
@@ -44,10 +45,10 @@ ObjDescT = TypeVar('ObjDescT')
44
45
 
45
46
 
46
47
  class ObjectDescription(SphinxDirective, Generic[ObjDescT]):
47
- """
48
- Directive to describe a class, function or similar object. Not used
49
- directly, but subclassed (in domain-specific directives) to add custom
50
- behavior.
48
+ """Directive to describe a class, function or similar object.
49
+
50
+ Not used directly, but subclassed (in domain-specific directives)
51
+ to add custom behaviour.
51
52
  """
52
53
 
53
54
  has_content = True
@@ -81,16 +82,16 @@ class ObjectDescription(SphinxDirective, Generic[ObjDescT]):
81
82
  self._doc_field_type_map[name] = (field, False)
82
83
 
83
84
  if field.is_typed:
84
- typed_field = cast(TypedField, field)
85
+ typed_field = cast('TypedField', field)
85
86
  for name in typed_field.typenames:
86
87
  self._doc_field_type_map[name] = (field, True)
87
88
 
88
89
  return self._doc_field_type_map
89
90
 
90
91
  def get_signatures(self) -> list[str]:
91
- """
92
- Retrieve the signatures to document from the directive arguments. By
93
- default, signatures are given as arguments, one per line.
92
+ """Retrieve the signatures to document from the directive arguments.
93
+
94
+ By default, signatures are given as arguments, one per line.
94
95
  """
95
96
  lines = nl_escape_re.sub('', self.arguments[0]).split('\n')
96
97
  if self.config.strip_signature_backslash:
@@ -100,9 +101,10 @@ class ObjectDescription(SphinxDirective, Generic[ObjDescT]):
100
101
  return [line.strip() for line in lines]
101
102
 
102
103
  def handle_signature(self, sig: str, signode: desc_signature) -> ObjDescT:
103
- """
104
- Parse the signature *sig* into individual nodes and append them to
105
- *signode*. If ValueError is raised, parsing is aborted and the whole
104
+ """Parse the signature *sig*.
105
+
106
+ The individual nodes are then appended to *signode*.
107
+ If ValueError is raised, parsing is aborted and the whole
106
108
  *sig* is put into a single desc_name node.
107
109
 
108
110
  The return value should be a value that identifies the object. It is
@@ -114,39 +116,39 @@ class ObjectDescription(SphinxDirective, Generic[ObjDescT]):
114
116
  def add_target_and_index(
115
117
  self, name: ObjDescT, sig: str, signode: desc_signature
116
118
  ) -> None:
117
- """
118
- Add cross-reference IDs and entries to self.indexnode, if applicable.
119
+ """Add cross-reference IDs and entries to self.indexnode, if applicable.
119
120
 
120
121
  *name* is whatever :meth:`handle_signature()` returned.
121
122
  """
122
123
  pass # do nothing by default
123
124
 
124
125
  def before_content(self) -> None:
125
- """
126
- Called before parsing content. Used to set information about the current
127
- directive context on the build environment.
126
+ """Called before parsing content.
127
+
128
+ Used to set information about the current directive context
129
+ on the build environment.
128
130
  """
129
131
  pass
130
132
 
131
133
  def transform_content(self, content_node: addnodes.desc_content) -> None:
132
- """
134
+ """Can be used to manipulate the content.
135
+
133
136
  Called after creating the content through nested parsing,
134
137
  but before the ``object-description-transform`` event is emitted,
135
138
  and before the info-fields are transformed.
136
- Can be used to manipulate the content.
137
139
  """
138
140
  pass
139
141
 
140
142
  def after_content(self) -> None:
141
- """
142
- Called after parsing content. Used to reset information about the
143
- current directive context on the build environment.
143
+ """Called after parsing content.
144
+
145
+ Used to reset information about the current directive context
146
+ on the build environment.
144
147
  """
145
148
  pass
146
149
 
147
150
  def _object_hierarchy_parts(self, sig_node: desc_signature) -> tuple[str, ...]:
148
- """
149
- Returns a tuple of strings, one entry for each part of the object's
151
+ """Returns a tuple of strings, one entry for each part of the object's
150
152
  hierarchy (e.g. ``('module', 'submodule', 'Class', 'method')``). The
151
153
  returned tuple is used to properly nest children within parents in the
152
154
  table of contents, and can also be used within the
@@ -157,8 +159,7 @@ class ObjectDescription(SphinxDirective, Generic[ObjDescT]):
157
159
  return ()
158
160
 
159
161
  def _toc_entry_name(self, sig_node: desc_signature) -> str:
160
- """
161
- Returns the text of the table of contents entry for the object.
162
+ """Returns the text of the table of contents entry for the object.
162
163
 
163
164
  This function is called once, in :py:meth:`run`, to set the name for the
164
165
  table of contents entry (a special attribute ``_toc_name`` is set on the
@@ -183,8 +184,7 @@ class ObjectDescription(SphinxDirective, Generic[ObjDescT]):
183
184
  return ''
184
185
 
185
186
  def run(self) -> list[Node]:
186
- """
187
- Main directive entry function, called by docutils upon encountering the
187
+ """Main directive entry function, called by docutils upon encountering the
188
188
  directive.
189
189
 
190
190
  This directive is meant to be quite easily subclassable, so it delegates
@@ -267,7 +267,7 @@ class ObjectDescription(SphinxDirective, Generic[ObjDescT]):
267
267
  finally:
268
268
  # Private attributes for ToC generation. Will be modified or removed
269
269
  # without notice.
270
- if self.env.app.config.toc_object_entries:
270
+ if self.config.toc_object_entries:
271
271
  signode['_toc_parts'] = self._object_hierarchy_parts(signode)
272
272
  signode['_toc_name'] = self._toc_entry_name(signode)
273
273
  else:
@@ -282,17 +282,21 @@ class ObjectDescription(SphinxDirective, Generic[ObjDescT]):
282
282
 
283
283
  if self.names:
284
284
  # needed for association of version{added,changed} directives
285
- self.env.temp_data['object'] = self.names[0]
285
+ object_name: ObjDescT = self.names[0]
286
+ if isinstance(object_name, tuple):
287
+ self.env.current_document.obj_desc_name = str(object_name[0])
288
+ else:
289
+ self.env.current_document.obj_desc_name = str(object_name)
286
290
  self.before_content()
287
291
  content_children = self.parse_content_to_nodes(allow_section_headings=True)
288
292
  content_node = addnodes.desc_content('', *content_children)
289
293
  node.append(content_node)
290
294
  self.transform_content(content_node)
291
- self.env.app.emit(
295
+ self.env.events.emit(
292
296
  'object-description-transform', self.domain, self.objtype, content_node
293
297
  )
294
298
  DocFieldTransformer(self).transform_all(content_node)
295
- self.env.temp_data['object'] = None
299
+ self.env.current_document.obj_desc_name = ''
296
300
  self.after_content()
297
301
 
298
302
  if node['no-typesetting']:
@@ -314,9 +318,7 @@ class ObjectDescription(SphinxDirective, Generic[ObjDescT]):
314
318
 
315
319
 
316
320
  class DefaultRole(SphinxDirective):
317
- """
318
- Set the default interpreted text role. Overridden from docutils.
319
- """
321
+ """Set the default interpreted text role. Overridden from docutils."""
320
322
 
321
323
  optional_arguments = 1
322
324
  final_argument_whitespace = False
@@ -331,7 +333,7 @@ class DefaultRole(SphinxDirective):
331
333
  )
332
334
  if role:
333
335
  docutils.register_role('', role) # type: ignore[arg-type]
334
- self.env.temp_data['default_role'] = role_name
336
+ self.env.current_document.default_role = role_name
335
337
  else:
336
338
  literal_block = nodes.literal_block(self.block_text, self.block_text)
337
339
  reporter = self.state.reporter
@@ -342,13 +344,11 @@ class DefaultRole(SphinxDirective):
342
344
  )
343
345
  messages += [error]
344
346
 
345
- return cast(list[nodes.Node], messages)
347
+ return cast('list[nodes.Node]', messages)
346
348
 
347
349
 
348
350
  class DefaultDomain(SphinxDirective):
349
- """
350
- Directive to (re-)set the default domain for this source file.
351
- """
351
+ """Directive to (re-)set the default domain for this source file."""
352
352
 
353
353
  has_content = False
354
354
  required_arguments = 1
@@ -358,18 +358,15 @@ class DefaultDomain(SphinxDirective):
358
358
 
359
359
  def run(self) -> list[Node]:
360
360
  domain_name = self.arguments[0].lower()
361
- # if domain_name not in env.domains:
362
- # # try searching by label
363
- # for domain in env.domains.sorted():
364
- # if domain.label.lower() == domain_name:
365
- # domain_name = domain.name
366
- # break
367
- self.env.temp_data['default_domain'] = self.env.domains.get(domain_name)
361
+ default_domain = self.env.domains.get(domain_name)
362
+ self.env.current_document.default_domain = default_domain
368
363
  return []
369
364
 
370
365
 
371
366
  def setup(app: Sphinx) -> ExtensionMetadata:
372
- app.add_config_value('strip_signature_backslash', False, 'env')
367
+ app.add_config_value(
368
+ 'strip_signature_backslash', False, 'env', types=frozenset({bool})
369
+ )
373
370
  directives.register_directive('default-role', DefaultRole)
374
371
  directives.register_directive('default-domain', DefaultDomain)
375
372
  directives.register_directive('describe', ObjectDescription)
@@ -0,0 +1,107 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from docutils import nodes
6
+ from docutils.parsers.rst.directives.admonitions import BaseAdmonition
7
+
8
+ from sphinx import addnodes
9
+ from sphinx.util.docutils import SphinxDirective
10
+
11
+ if TYPE_CHECKING:
12
+ from typing import ClassVar
13
+
14
+ from docutils.nodes import Node
15
+
16
+ from sphinx.application import Sphinx
17
+ from sphinx.util.typing import ExtensionMetadata, OptionSpec
18
+
19
+
20
+ def _collapsible_arg(argument: str | None) -> str:
21
+ if argument is None:
22
+ return 'open'
23
+ if (value := argument.lower().strip()) in {'open', 'closed'}:
24
+ return value
25
+ msg = f'"{argument}" unknown; choose from "open" or "closed".'
26
+ raise ValueError(msg)
27
+
28
+
29
+ class SphinxAdmonition(BaseAdmonition, SphinxDirective):
30
+ option_spec: ClassVar[OptionSpec] = BaseAdmonition.option_spec.copy() # type: ignore[union-attr]
31
+ option_spec |= {
32
+ 'collapsible': _collapsible_arg,
33
+ }
34
+
35
+ node_class: type[nodes.Admonition] = nodes.admonition
36
+ """Subclasses must set this to the appropriate admonition node class."""
37
+
38
+ def run(self) -> list[Node]:
39
+ (admonition_node,) = super().run()
40
+ return [admonition_node]
41
+
42
+
43
+ class Admonition(SphinxAdmonition):
44
+ required_arguments = 1
45
+ node_class = nodes.admonition
46
+
47
+
48
+ class Attention(SphinxAdmonition):
49
+ node_class = nodes.attention
50
+
51
+
52
+ class Caution(SphinxAdmonition):
53
+ node_class = nodes.caution
54
+
55
+
56
+ class Danger(SphinxAdmonition):
57
+ node_class = nodes.danger
58
+
59
+
60
+ class Error(SphinxAdmonition):
61
+ node_class = nodes.error
62
+
63
+
64
+ class Hint(SphinxAdmonition):
65
+ node_class = nodes.hint
66
+
67
+
68
+ class Important(SphinxAdmonition):
69
+ node_class = nodes.important
70
+
71
+
72
+ class Note(SphinxAdmonition):
73
+ node_class = nodes.note
74
+
75
+
76
+ class Tip(SphinxAdmonition):
77
+ node_class = nodes.tip
78
+
79
+
80
+ class Warning(SphinxAdmonition):
81
+ node_class = nodes.warning
82
+
83
+
84
+ class SeeAlso(SphinxAdmonition):
85
+ """An admonition mentioning things to look at as reference."""
86
+
87
+ node_class = addnodes.seealso
88
+
89
+
90
+ def setup(app: Sphinx) -> ExtensionMetadata:
91
+ app.add_directive('admonition', Admonition, override=True)
92
+ app.add_directive('attention', Attention, override=True)
93
+ app.add_directive('caution', Caution, override=True)
94
+ app.add_directive('danger', Danger, override=True)
95
+ app.add_directive('error', Error, override=True)
96
+ app.add_directive('hint', Hint, override=True)
97
+ app.add_directive('important', Important, override=True)
98
+ app.add_directive('note', Note, override=True)
99
+ app.add_directive('tip', Tip, override=True)
100
+ app.add_directive('warning', Warning, override=True)
101
+ app.add_directive('seealso', SeeAlso, override=True)
102
+
103
+ return {
104
+ 'version': 'builtin',
105
+ 'parallel_read_safe': True,
106
+ 'parallel_write_safe': True,
107
+ }
sphinx/directives/code.py CHANGED
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import sys
4
4
  import textwrap
5
5
  from difflib import unified_diff
6
- from typing import TYPE_CHECKING, Any, ClassVar
6
+ from typing import TYPE_CHECKING
7
7
 
8
8
  from docutils import nodes
9
9
  from docutils.parsers.rst import directives
@@ -13,9 +13,13 @@ from sphinx.directives import optional_int
13
13
  from sphinx.locale import __
14
14
  from sphinx.util import logging
15
15
  from sphinx.util._lines import parse_line_num_spec
16
+ from sphinx.util._pathlib import _StrPath
16
17
  from sphinx.util.docutils import SphinxDirective
17
18
 
18
19
  if TYPE_CHECKING:
20
+ import os
21
+ from typing import Any, ClassVar
22
+
19
23
  from docutils.nodes import Element, Node
20
24
 
21
25
  from sphinx.application import Sphinx
@@ -26,8 +30,7 @@ logger = logging.getLogger(__name__)
26
30
 
27
31
 
28
32
  class Highlight(SphinxDirective):
29
- """
30
- Directive to set the highlighting language for code blocks, as well
33
+ """Directive to set the highlighting language for code blocks, as well
31
34
  as the threshold for line numbers.
32
35
  """
33
36
 
@@ -45,7 +48,7 @@ class Highlight(SphinxDirective):
45
48
  linenothreshold = self.options.get('linenothreshold', sys.maxsize)
46
49
  force = 'force' in self.options
47
50
 
48
- self.env.temp_data['highlight_language'] = language
51
+ self.env.current_document.highlight_language = language
49
52
  return [
50
53
  addnodes.highlightlang(
51
54
  lang=language, force=force, linenothreshold=linenothreshold
@@ -82,7 +85,7 @@ def container_wrapper(
82
85
  node = parsed[0]
83
86
  if isinstance(node, nodes.system_message):
84
87
  msg = __('Invalid caption: %s') % node.astext()
85
- raise ValueError(msg)
88
+ raise ValueError(msg) # NoQA: TRY004
86
89
  if isinstance(node, nodes.Element):
87
90
  caption_node = nodes.caption(node.rawsource, '', *node.children)
88
91
  caption_node.source = literal_node.source
@@ -94,8 +97,7 @@ def container_wrapper(
94
97
 
95
98
 
96
99
  class CodeBlock(SphinxDirective):
97
- """
98
- Directive for a code block with special highlighting or line numbering
100
+ """Directive for a code block with special highlighting or line numbering
99
101
  settings.
100
102
  """
101
103
 
@@ -156,8 +158,9 @@ class CodeBlock(SphinxDirective):
156
158
  # no highlight language specified. Then this directive refers the current
157
159
  # highlight setting via ``highlight`` directive or ``highlight_language``
158
160
  # configuration.
159
- literal['language'] = self.env.temp_data.get(
160
- 'highlight_language', self.config.highlight_language
161
+ literal['language'] = (
162
+ self.env.current_document.highlight_language
163
+ or self.config.highlight_language
161
164
  )
162
165
  extra_args = literal['highlight_args'] = {}
163
166
  if hl_lines is not None:
@@ -197,8 +200,10 @@ class LiteralIncludeReader:
197
200
  ('diff', 'end-at'),
198
201
  ]
199
202
 
200
- def __init__(self, filename: str, options: dict[str, Any], config: Config) -> None:
201
- self.filename = filename
203
+ def __init__(
204
+ self, filename: str | os.PathLike[str], options: dict[str, Any], config: Config
205
+ ) -> None:
206
+ self.filename = _StrPath(filename)
202
207
  self.options = options
203
208
  self.encoding = options.get('encoding', config.source_encoding)
204
209
  self.lineno_start = self.options.get('lineno-start', 1)
@@ -212,21 +217,22 @@ class LiteralIncludeReader:
212
217
  raise ValueError(msg)
213
218
 
214
219
  def read_file(
215
- self, filename: str, location: tuple[str, int] | None = None
220
+ self, filename: str | os.PathLike[str], location: tuple[str, int] | None = None
216
221
  ) -> list[str]:
222
+ filename = _StrPath(filename)
217
223
  try:
218
224
  with open(filename, encoding=self.encoding, errors='strict') as f:
219
225
  text = f.read()
220
- if 'tab-width' in self.options:
221
- text = text.expandtabs(self.options['tab-width'])
226
+ if 'tab-width' in self.options:
227
+ text = text.expandtabs(self.options['tab-width'])
222
228
 
223
- return text.splitlines(True)
229
+ return text.splitlines(True)
224
230
  except OSError as exc:
225
- msg = __('Include file %r not found or reading it failed') % filename
231
+ msg = __("Include file '%s' not found or reading it failed") % filename
226
232
  raise OSError(msg) from exc
227
233
  except UnicodeError as exc:
228
234
  msg = __(
229
- 'Encoding %r used for reading included file %r seems to '
235
+ "Encoding %r used for reading included file '%s' seems to "
230
236
  'be wrong, try giving an :encoding: option'
231
237
  ) % (self.encoding, filename)
232
238
  raise UnicodeError(msg) from exc
@@ -403,8 +409,7 @@ class LiteralIncludeReader:
403
409
 
404
410
 
405
411
  class LiteralInclude(SphinxDirective):
406
- """
407
- Like ``.. include:: :literal:``, but only warns if the include file is
412
+ """Like ``.. include:: :literal:``, but only warns if the include file is
408
413
  not found, and does not raise errors. Also has several options for
409
414
  selecting what to include.
410
415
  """
@@ -1,13 +1,12 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import re
4
- from os.path import abspath, relpath
4
+ from os.path import relpath
5
5
  from pathlib import Path
6
- from typing import TYPE_CHECKING, Any, ClassVar, cast
6
+ from typing import TYPE_CHECKING, cast
7
7
 
8
8
  from docutils import nodes
9
9
  from docutils.parsers.rst import directives
10
- from docutils.parsers.rst.directives.admonitions import BaseAdmonition
11
10
  from docutils.parsers.rst.directives.misc import Class
12
11
  from docutils.parsers.rst.directives.misc import Include as BaseInclude
13
12
  from docutils.statemachine import StateMachine
@@ -22,6 +21,7 @@ from sphinx.util.nodes import explicit_title_re
22
21
 
23
22
  if TYPE_CHECKING:
24
23
  from collections.abc import Sequence
24
+ from typing import Any, ClassVar
25
25
 
26
26
  from docutils.nodes import Element, Node
27
27
 
@@ -40,8 +40,7 @@ def int_or_nothing(argument: str) -> int:
40
40
 
41
41
 
42
42
  class TocTree(SphinxDirective):
43
- """
44
- Directive to notify Sphinx about the hierarchical structure of the docs,
43
+ """Directive to notify Sphinx about the hierarchical structure of the docs,
45
44
  and to include a table-of-contents like tree in the current document.
46
45
  """
47
46
 
@@ -88,9 +87,7 @@ class TocTree(SphinxDirective):
88
87
  return [wrappernode]
89
88
 
90
89
  def parse_content(self, toctree: addnodes.toctree) -> None:
91
- """
92
- Populate ``toctree['entries']`` and ``toctree['includefiles']`` from content.
93
- """
90
+ """Populate ``toctree['entries']`` and ``toctree['includefiles']`` from content."""
94
91
  generated_docnames = frozenset(StandardDomain._virtual_doc_names)
95
92
  suffixes = self.config.source_suffix
96
93
  current_docname = self.env.docname
@@ -122,6 +119,7 @@ class TocTree(SphinxDirective):
122
119
  __("toctree glob pattern %r didn't match any documents"),
123
120
  entry,
124
121
  location=toctree,
122
+ subtype='empty_glob',
125
123
  )
126
124
 
127
125
  for docname in doc_names:
@@ -159,7 +157,7 @@ class TocTree(SphinxDirective):
159
157
  subtype = 'not_readable'
160
158
 
161
159
  logger.warning(
162
- msg, docname, type='toc', subtype=subtype, location=toctree
160
+ msg, docname, location=toctree, type='toc', subtype=subtype
163
161
  )
164
162
  self.env.note_reread()
165
163
  continue
@@ -171,6 +169,8 @@ class TocTree(SphinxDirective):
171
169
  __('duplicated entry found in toctree: %s'),
172
170
  docname,
173
171
  location=toctree,
172
+ type='toc',
173
+ subtype='duplicate_entry',
174
174
  )
175
175
 
176
176
  toctree['entries'].append((title, docname))
@@ -183,8 +183,7 @@ class TocTree(SphinxDirective):
183
183
 
184
184
 
185
185
  class Author(SphinxDirective):
186
- """
187
- Directive to give the name of the author of the current document
186
+ """Directive to give the name of the author of the current document
188
187
  or section. Shown in the output only if the show_authors option is on.
189
188
  """
190
189
 
@@ -217,18 +216,8 @@ class Author(SphinxDirective):
217
216
  return ret
218
217
 
219
218
 
220
- class SeeAlso(BaseAdmonition):
221
- """
222
- An admonition mentioning things to look at as reference.
223
- """
224
-
225
- node_class = addnodes.seealso
226
-
227
-
228
219
  class TabularColumns(SphinxDirective):
229
- """
230
- Directive to give an explicit tabulary column definition to LaTeX.
231
- """
220
+ """Directive to give an explicit tabulary column definition to LaTeX."""
232
221
 
233
222
  has_content = False
234
223
  required_arguments = 1
@@ -244,9 +233,7 @@ class TabularColumns(SphinxDirective):
244
233
 
245
234
 
246
235
  class Centered(SphinxDirective):
247
- """
248
- Directive to create a centered line of bold text.
249
- """
236
+ """Directive to create a centered line of bold text."""
250
237
 
251
238
  has_content = False
252
239
  required_arguments = 1
@@ -267,9 +254,7 @@ class Centered(SphinxDirective):
267
254
 
268
255
 
269
256
  class Acks(SphinxDirective):
270
- """
271
- Directive for a list of names.
272
- """
257
+ """Directive for a list of names."""
273
258
 
274
259
  has_content = True
275
260
  required_arguments = 0
@@ -289,9 +274,7 @@ class Acks(SphinxDirective):
289
274
 
290
275
 
291
276
  class HList(SphinxDirective):
292
- """
293
- Directive for a list that gets compacted horizontally.
294
- """
277
+ """Directive for a list that gets compacted horizontally."""
295
278
 
296
279
  has_content = True
297
280
  required_arguments = 0
@@ -326,9 +309,7 @@ class HList(SphinxDirective):
326
309
 
327
310
 
328
311
  class Only(SphinxDirective):
329
- """
330
- Directive to only include text if the given tag(s) are enabled.
331
- """
312
+ """Directive to only include text if the given tag(s) are enabled."""
332
313
 
333
314
  has_content = True
334
315
  required_arguments = 1
@@ -376,7 +357,7 @@ class Only(SphinxDirective):
376
357
  # Use these depths to determine where the nested sections should
377
358
  # be placed in the doctree.
378
359
  n_sects_to_raise = current_depth - nested_depth + 1
379
- parent = cast(nodes.Element, self.state.parent)
360
+ parent = cast('nodes.Element', self.state.parent)
380
361
  for _i in range(n_sects_to_raise):
381
362
  if parent.parent:
382
363
  parent = parent.parent
@@ -388,8 +369,7 @@ class Only(SphinxDirective):
388
369
 
389
370
 
390
371
  class Include(BaseInclude, SphinxDirective):
391
- """
392
- Like the standard "Include" directive, but interprets absolute paths
372
+ """Like the standard "Include" directive, but interprets absolute paths
393
373
  "correctly", i.e. relative to source directory.
394
374
  """
395
375
 
@@ -407,12 +387,12 @@ class Include(BaseInclude, SphinxDirective):
407
387
  # We must preserve them and leave them out of the include-read event:
408
388
  text = '\n'.join(include_lines[:-2])
409
389
 
410
- path = Path(relpath(abspath(source), start=self.env.srcdir))
390
+ path = Path(relpath(Path(source).resolve(), start=self.env.srcdir))
411
391
  docname = self.env.docname
412
392
 
413
393
  # Emit the "include-read" event
414
394
  arg = [text]
415
- self.env.app.events.emit('include-read', path, docname, arg)
395
+ self.env.events.emit('include-read', path, docname, arg)
416
396
  text = arg[0]
417
397
 
418
398
  # Split back into lines and reattach the two marker lines
@@ -424,7 +404,7 @@ class Include(BaseInclude, SphinxDirective):
424
404
  return StateMachine.insert_input(self.state_machine, include_lines, source)
425
405
 
426
406
  # Only enable this patch if there are listeners for 'include-read'.
427
- if self.env.app.events.listeners.get('include-read'):
407
+ if self.env.events.listeners.get('include-read'):
428
408
  # See https://github.com/python/mypy/issues/2427 for details on the mypy issue
429
409
  self.state_machine.insert_input = _insert_input
430
410
 
@@ -432,7 +412,7 @@ class Include(BaseInclude, SphinxDirective):
432
412
  # docutils "standard" includes, do not do path processing
433
413
  return super().run()
434
414
  rel_filename, filename = self.env.relfn2path(self.arguments[0])
435
- self.arguments[0] = filename
415
+ self.arguments[0] = str(filename)
436
416
  self.env.note_included(filename)
437
417
  return super().run()
438
418
 
@@ -442,7 +422,6 @@ def setup(app: Sphinx) -> ExtensionMetadata:
442
422
  directives.register_directive('sectionauthor', Author)
443
423
  directives.register_directive('moduleauthor', Author)
444
424
  directives.register_directive('codeauthor', Author)
445
- directives.register_directive('seealso', SeeAlso)
446
425
  directives.register_directive('tabularcolumns', TabularColumns)
447
426
  directives.register_directive('centered', Centered)
448
427
  directives.register_directive('acks', Acks)