Sphinx 7.1.2__py3-none-any.whl → 7.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 (313) hide show
  1. sphinx/__init__.py +6 -6
  2. sphinx/__main__.py +3 -1
  3. sphinx/addnodes.py +35 -22
  4. sphinx/application.py +40 -38
  5. sphinx/builders/__init__.py +16 -12
  6. sphinx/builders/_epub_base.py +15 -11
  7. sphinx/builders/changes.py +6 -4
  8. sphinx/builders/dirhtml.py +4 -2
  9. sphinx/builders/dummy.py +6 -4
  10. sphinx/builders/epub3.py +16 -8
  11. sphinx/builders/gettext.py +40 -43
  12. sphinx/builders/html/__init__.py +166 -196
  13. sphinx/builders/html/_assets.py +116 -0
  14. sphinx/builders/html/transforms.py +4 -2
  15. sphinx/builders/latex/__init__.py +12 -7
  16. sphinx/builders/latex/theming.py +5 -2
  17. sphinx/builders/latex/transforms.py +6 -3
  18. sphinx/builders/linkcheck.py +18 -11
  19. sphinx/builders/manpage.py +6 -4
  20. sphinx/builders/singlehtml.py +16 -9
  21. sphinx/builders/texinfo.py +11 -6
  22. sphinx/builders/text.py +8 -3
  23. sphinx/builders/xml.py +9 -4
  24. sphinx/cmd/build.py +27 -14
  25. sphinx/cmd/make_mode.py +13 -4
  26. sphinx/cmd/quickstart.py +13 -4
  27. sphinx/config.py +17 -14
  28. sphinx/deprecation.py +4 -2
  29. sphinx/directives/__init__.py +44 -12
  30. sphinx/directives/code.py +5 -4
  31. sphinx/directives/other.py +92 -44
  32. sphinx/directives/patches.py +1 -1
  33. sphinx/domains/__init__.py +11 -8
  34. sphinx/domains/c.py +67 -57
  35. sphinx/domains/changeset.py +3 -2
  36. sphinx/domains/citation.py +2 -1
  37. sphinx/domains/cpp.py +136 -93
  38. sphinx/domains/index.py +9 -5
  39. sphinx/domains/javascript.py +32 -19
  40. sphinx/domains/math.py +5 -3
  41. sphinx/domains/python.py +69 -57
  42. sphinx/domains/rst.py +20 -11
  43. sphinx/domains/std.py +21 -15
  44. sphinx/environment/__init__.py +97 -65
  45. sphinx/environment/adapters/indexentries.py +13 -10
  46. sphinx/environment/adapters/toctree.py +485 -308
  47. sphinx/environment/collectors/__init__.py +3 -4
  48. sphinx/environment/collectors/asset.py +10 -4
  49. sphinx/environment/collectors/dependencies.py +7 -4
  50. sphinx/environment/collectors/metadata.py +7 -5
  51. sphinx/environment/collectors/title.py +5 -3
  52. sphinx/environment/collectors/toctree.py +13 -8
  53. sphinx/errors.py +1 -1
  54. sphinx/events.py +5 -5
  55. sphinx/ext/apidoc.py +49 -27
  56. sphinx/ext/autodoc/__init__.py +179 -161
  57. sphinx/ext/autodoc/directive.py +10 -6
  58. sphinx/ext/autodoc/importer.py +22 -13
  59. sphinx/ext/autodoc/mock.py +4 -1
  60. sphinx/ext/autodoc/preserve_defaults.py +80 -12
  61. sphinx/ext/autodoc/type_comment.py +14 -10
  62. sphinx/ext/autodoc/typehints.py +7 -3
  63. sphinx/ext/autosectionlabel.py +6 -3
  64. sphinx/ext/autosummary/__init__.py +21 -15
  65. sphinx/ext/autosummary/generate.py +176 -126
  66. sphinx/ext/coverage.py +93 -8
  67. sphinx/ext/doctest.py +28 -17
  68. sphinx/ext/duration.py +19 -17
  69. sphinx/ext/extlinks.py +11 -6
  70. sphinx/ext/githubpages.py +8 -7
  71. sphinx/ext/graphviz.py +61 -17
  72. sphinx/ext/ifconfig.py +7 -4
  73. sphinx/ext/imgconverter.py +4 -2
  74. sphinx/ext/imgmath.py +29 -23
  75. sphinx/ext/inheritance_diagram.py +41 -27
  76. sphinx/ext/intersphinx.py +45 -38
  77. sphinx/ext/linkcode.py +8 -5
  78. sphinx/ext/mathjax.py +13 -9
  79. sphinx/ext/napoleon/__init__.py +3 -3
  80. sphinx/ext/napoleon/docstring.py +40 -31
  81. sphinx/ext/todo.py +10 -7
  82. sphinx/ext/viewcode.py +46 -25
  83. sphinx/extension.py +1 -1
  84. sphinx/highlighting.py +20 -12
  85. sphinx/io.py +5 -4
  86. sphinx/jinja2glue.py +24 -19
  87. sphinx/locale/__init__.py +8 -2
  88. sphinx/locale/ar/LC_MESSAGES/sphinx.mo +0 -0
  89. sphinx/locale/ar/LC_MESSAGES/sphinx.po +756 -740
  90. sphinx/locale/bg/LC_MESSAGES/sphinx.mo +0 -0
  91. sphinx/locale/bg/LC_MESSAGES/sphinx.po +754 -738
  92. sphinx/locale/bn/LC_MESSAGES/sphinx.mo +0 -0
  93. sphinx/locale/bn/LC_MESSAGES/sphinx.po +755 -739
  94. sphinx/locale/ca/LC_MESSAGES/sphinx.mo +0 -0
  95. sphinx/locale/ca/LC_MESSAGES/sphinx.po +768 -752
  96. sphinx/locale/cak/LC_MESSAGES/sphinx.mo +0 -0
  97. sphinx/locale/cak/LC_MESSAGES/sphinx.po +754 -738
  98. sphinx/locale/cs/LC_MESSAGES/sphinx.mo +0 -0
  99. sphinx/locale/cs/LC_MESSAGES/sphinx.po +758 -742
  100. sphinx/locale/cy/LC_MESSAGES/sphinx.mo +0 -0
  101. sphinx/locale/cy/LC_MESSAGES/sphinx.po +759 -743
  102. sphinx/locale/da/LC_MESSAGES/sphinx.mo +0 -0
  103. sphinx/locale/da/LC_MESSAGES/sphinx.po +760 -744
  104. sphinx/locale/de/LC_MESSAGES/sphinx.mo +0 -0
  105. sphinx/locale/de/LC_MESSAGES/sphinx.po +759 -743
  106. sphinx/locale/de_DE/LC_MESSAGES/sphinx.mo +0 -0
  107. sphinx/locale/de_DE/LC_MESSAGES/sphinx.po +754 -738
  108. sphinx/locale/el/LC_MESSAGES/sphinx.mo +0 -0
  109. sphinx/locale/el/LC_MESSAGES/sphinx.po +763 -747
  110. sphinx/locale/en_DE/LC_MESSAGES/sphinx.mo +0 -0
  111. sphinx/locale/en_DE/LC_MESSAGES/sphinx.po +754 -738
  112. sphinx/locale/en_FR/LC_MESSAGES/sphinx.mo +0 -0
  113. sphinx/locale/en_FR/LC_MESSAGES/sphinx.po +754 -738
  114. sphinx/locale/en_GB/LC_MESSAGES/sphinx.mo +0 -0
  115. sphinx/locale/en_GB/LC_MESSAGES/sphinx.po +768 -752
  116. sphinx/locale/en_HK/LC_MESSAGES/sphinx.mo +0 -0
  117. sphinx/locale/en_HK/LC_MESSAGES/sphinx.po +754 -738
  118. sphinx/locale/eo/LC_MESSAGES/sphinx.mo +0 -0
  119. sphinx/locale/eo/LC_MESSAGES/sphinx.po +754 -738
  120. sphinx/locale/es/LC_MESSAGES/sphinx.mo +0 -0
  121. sphinx/locale/es/LC_MESSAGES/sphinx.po +767 -751
  122. sphinx/locale/es_CO/LC_MESSAGES/sphinx.mo +0 -0
  123. sphinx/locale/es_CO/LC_MESSAGES/sphinx.po +754 -738
  124. sphinx/locale/et/LC_MESSAGES/sphinx.mo +0 -0
  125. sphinx/locale/et/LC_MESSAGES/sphinx.po +762 -746
  126. sphinx/locale/eu/LC_MESSAGES/sphinx.mo +0 -0
  127. sphinx/locale/eu/LC_MESSAGES/sphinx.po +755 -739
  128. sphinx/locale/fa/LC_MESSAGES/sphinx.mo +0 -0
  129. sphinx/locale/fa/LC_MESSAGES/sphinx.po +766 -750
  130. sphinx/locale/fi/LC_MESSAGES/sphinx.mo +0 -0
  131. sphinx/locale/fi/LC_MESSAGES/sphinx.po +754 -738
  132. sphinx/locale/fr/LC_MESSAGES/sphinx.mo +0 -0
  133. sphinx/locale/fr/LC_MESSAGES/sphinx.po +768 -752
  134. sphinx/locale/fr_FR/LC_MESSAGES/sphinx.mo +0 -0
  135. sphinx/locale/fr_FR/LC_MESSAGES/sphinx.po +754 -738
  136. sphinx/locale/gl/LC_MESSAGES/sphinx.js +60 -0
  137. sphinx/locale/gl/LC_MESSAGES/sphinx.mo +0 -0
  138. sphinx/locale/gl/LC_MESSAGES/sphinx.po +3695 -0
  139. sphinx/locale/he/LC_MESSAGES/sphinx.mo +0 -0
  140. sphinx/locale/he/LC_MESSAGES/sphinx.po +755 -739
  141. sphinx/locale/hi/LC_MESSAGES/sphinx.mo +0 -0
  142. sphinx/locale/hi/LC_MESSAGES/sphinx.po +763 -747
  143. sphinx/locale/hi_IN/LC_MESSAGES/sphinx.mo +0 -0
  144. sphinx/locale/hi_IN/LC_MESSAGES/sphinx.po +754 -738
  145. sphinx/locale/hr/LC_MESSAGES/sphinx.mo +0 -0
  146. sphinx/locale/hr/LC_MESSAGES/sphinx.po +760 -744
  147. sphinx/locale/hu/LC_MESSAGES/sphinx.mo +0 -0
  148. sphinx/locale/hu/LC_MESSAGES/sphinx.po +759 -743
  149. sphinx/locale/id/LC_MESSAGES/sphinx.mo +0 -0
  150. sphinx/locale/id/LC_MESSAGES/sphinx.po +765 -749
  151. sphinx/locale/is/LC_MESSAGES/sphinx.mo +0 -0
  152. sphinx/locale/is/LC_MESSAGES/sphinx.po +760 -744
  153. sphinx/locale/it/LC_MESSAGES/sphinx.mo +0 -0
  154. sphinx/locale/it/LC_MESSAGES/sphinx.po +760 -744
  155. sphinx/locale/ja/LC_MESSAGES/sphinx.mo +0 -0
  156. sphinx/locale/ja/LC_MESSAGES/sphinx.po +767 -751
  157. sphinx/locale/ka/LC_MESSAGES/sphinx.mo +0 -0
  158. sphinx/locale/ka/LC_MESSAGES/sphinx.po +759 -743
  159. sphinx/locale/ko/LC_MESSAGES/sphinx.mo +0 -0
  160. sphinx/locale/ko/LC_MESSAGES/sphinx.po +767 -751
  161. sphinx/locale/lt/LC_MESSAGES/sphinx.mo +0 -0
  162. sphinx/locale/lt/LC_MESSAGES/sphinx.po +755 -739
  163. sphinx/locale/lv/LC_MESSAGES/sphinx.mo +0 -0
  164. sphinx/locale/lv/LC_MESSAGES/sphinx.po +755 -739
  165. sphinx/locale/mk/LC_MESSAGES/sphinx.mo +0 -0
  166. sphinx/locale/mk/LC_MESSAGES/sphinx.po +754 -738
  167. sphinx/locale/nb_NO/LC_MESSAGES/sphinx.mo +0 -0
  168. sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po +755 -739
  169. sphinx/locale/ne/LC_MESSAGES/sphinx.mo +0 -0
  170. sphinx/locale/ne/LC_MESSAGES/sphinx.po +755 -739
  171. sphinx/locale/nl/LC_MESSAGES/sphinx.mo +0 -0
  172. sphinx/locale/nl/LC_MESSAGES/sphinx.po +760 -744
  173. sphinx/locale/pl/LC_MESSAGES/sphinx.mo +0 -0
  174. sphinx/locale/pl/LC_MESSAGES/sphinx.po +762 -745
  175. sphinx/locale/pt/LC_MESSAGES/sphinx.mo +0 -0
  176. sphinx/locale/pt/LC_MESSAGES/sphinx.po +754 -738
  177. sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo +0 -0
  178. sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po +768 -752
  179. sphinx/locale/pt_PT/LC_MESSAGES/sphinx.mo +0 -0
  180. sphinx/locale/pt_PT/LC_MESSAGES/sphinx.po +755 -739
  181. sphinx/locale/ro/LC_MESSAGES/sphinx.mo +0 -0
  182. sphinx/locale/ro/LC_MESSAGES/sphinx.po +759 -743
  183. sphinx/locale/ru/LC_MESSAGES/sphinx.mo +0 -0
  184. sphinx/locale/ru/LC_MESSAGES/sphinx.po +760 -744
  185. sphinx/locale/si/LC_MESSAGES/sphinx.mo +0 -0
  186. sphinx/locale/si/LC_MESSAGES/sphinx.po +754 -738
  187. sphinx/locale/sk/LC_MESSAGES/sphinx.mo +0 -0
  188. sphinx/locale/sk/LC_MESSAGES/sphinx.po +765 -749
  189. sphinx/locale/sl/LC_MESSAGES/sphinx.mo +0 -0
  190. sphinx/locale/sl/LC_MESSAGES/sphinx.po +755 -739
  191. sphinx/locale/sphinx.pot +748 -740
  192. sphinx/locale/sq/LC_MESSAGES/sphinx.mo +0 -0
  193. sphinx/locale/sq/LC_MESSAGES/sphinx.po +768 -752
  194. sphinx/locale/sr/LC_MESSAGES/sphinx.mo +0 -0
  195. sphinx/locale/sr/LC_MESSAGES/sphinx.po +754 -738
  196. sphinx/locale/sr@latin/LC_MESSAGES/sphinx.mo +0 -0
  197. sphinx/locale/sr@latin/LC_MESSAGES/sphinx.po +754 -738
  198. sphinx/locale/sr_RS/LC_MESSAGES/sphinx.mo +0 -0
  199. sphinx/locale/sr_RS/LC_MESSAGES/sphinx.po +754 -738
  200. sphinx/locale/sv/LC_MESSAGES/sphinx.mo +0 -0
  201. sphinx/locale/sv/LC_MESSAGES/sphinx.po +755 -739
  202. sphinx/locale/ta/LC_MESSAGES/sphinx.mo +0 -0
  203. sphinx/locale/ta/LC_MESSAGES/sphinx.po +754 -738
  204. sphinx/locale/te/LC_MESSAGES/sphinx.mo +0 -0
  205. sphinx/locale/te/LC_MESSAGES/sphinx.po +754 -738
  206. sphinx/locale/tr/LC_MESSAGES/sphinx.mo +0 -0
  207. sphinx/locale/tr/LC_MESSAGES/sphinx.po +763 -747
  208. sphinx/locale/uk_UA/LC_MESSAGES/sphinx.mo +0 -0
  209. sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po +760 -749
  210. sphinx/locale/ur/LC_MESSAGES/sphinx.mo +0 -0
  211. sphinx/locale/ur/LC_MESSAGES/sphinx.po +759 -748
  212. sphinx/locale/vi/LC_MESSAGES/sphinx.mo +0 -0
  213. sphinx/locale/vi/LC_MESSAGES/sphinx.po +754 -738
  214. sphinx/locale/yue/LC_MESSAGES/sphinx.mo +0 -0
  215. sphinx/locale/yue/LC_MESSAGES/sphinx.po +754 -738
  216. sphinx/locale/zh_CN/LC_MESSAGES/sphinx.mo +0 -0
  217. sphinx/locale/zh_CN/LC_MESSAGES/sphinx.po +768 -752
  218. sphinx/locale/zh_HK/LC_MESSAGES/sphinx.mo +0 -0
  219. sphinx/locale/zh_HK/LC_MESSAGES/sphinx.po +754 -738
  220. sphinx/locale/zh_TW/LC_MESSAGES/sphinx.mo +0 -0
  221. sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po +767 -751
  222. sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.mo +0 -0
  223. sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.po +754 -738
  224. sphinx/parsers.py +5 -4
  225. sphinx/project.py +52 -34
  226. sphinx/pycode/__init__.py +2 -1
  227. sphinx/pycode/ast.py +7 -13
  228. sphinx/pycode/parser.py +42 -38
  229. sphinx/registry.py +35 -29
  230. sphinx/roles.py +9 -4
  231. sphinx/search/__init__.py +5 -17
  232. sphinx/search/da.py +1 -1
  233. sphinx/search/de.py +1 -1
  234. sphinx/search/en.py +1 -1
  235. sphinx/search/es.py +1 -1
  236. sphinx/search/fi.py +1 -1
  237. sphinx/search/fr.py +1 -1
  238. sphinx/search/hu.py +1 -1
  239. sphinx/search/it.py +1 -1
  240. sphinx/search/ja.py +1 -1
  241. sphinx/search/nl.py +1 -1
  242. sphinx/search/no.py +1 -1
  243. sphinx/search/pt.py +1 -1
  244. sphinx/search/ro.py +1 -1
  245. sphinx/search/ru.py +1 -1
  246. sphinx/search/sv.py +1 -1
  247. sphinx/search/tr.py +1 -1
  248. sphinx/search/zh.py +1 -1
  249. sphinx/testing/fixtures.py +23 -30
  250. sphinx/testing/path.py +9 -0
  251. sphinx/testing/restructuredtext.py +13 -5
  252. sphinx/testing/util.py +20 -63
  253. sphinx/texinputs/sphinxlatexobjects.sty +15 -15
  254. sphinx/themes/agogo/static/agogo.css_t +10 -4
  255. sphinx/themes/basic/layout.html +1 -1
  256. sphinx/themes/basic/static/basic.css_t +4 -0
  257. sphinx/themes/basic/static/documentation_options.js_t +1 -2
  258. sphinx/themes/basic/static/searchtools.js +17 -9
  259. sphinx/themes/basic/static/sphinx_highlight.js +13 -3
  260. sphinx/themes/bizstyle/static/bizstyle.css_t +4 -0
  261. sphinx/themes/classic/theme.conf +1 -1
  262. sphinx/themes/epub/static/epub.css_t +6 -1
  263. sphinx/themes/haiku/theme.conf +1 -1
  264. sphinx/themes/nature/static/nature.css_t +4 -0
  265. sphinx/themes/nonav/static/nonav.css_t +6 -1
  266. sphinx/themes/pyramid/static/pyramid.css_t +4 -0
  267. sphinx/themes/scrolls/static/scrolls.css_t +4 -0
  268. sphinx/themes/scrolls/theme.conf +1 -1
  269. sphinx/themes/sphinxdoc/static/sphinxdoc.css_t +4 -0
  270. sphinx/theming.py +9 -7
  271. sphinx/transforms/__init__.py +79 -3
  272. sphinx/transforms/compact_bullet_list.py +6 -3
  273. sphinx/transforms/i18n.py +26 -10
  274. sphinx/transforms/post_transforms/__init__.py +21 -8
  275. sphinx/transforms/post_transforms/code.py +6 -3
  276. sphinx/transforms/post_transforms/images.py +13 -9
  277. sphinx/util/__init__.py +21 -92
  278. sphinx/util/cfamily.py +7 -4
  279. sphinx/util/display.py +3 -2
  280. sphinx/util/docfields.py +7 -6
  281. sphinx/util/docstrings.py +1 -1
  282. sphinx/util/docutils.py +41 -31
  283. sphinx/util/fileutil.py +9 -6
  284. sphinx/util/i18n.py +21 -18
  285. sphinx/util/images.py +2 -1
  286. sphinx/util/index_entries.py +27 -0
  287. sphinx/util/inspect.py +83 -67
  288. sphinx/util/inventory.py +4 -2
  289. sphinx/util/logging.py +9 -6
  290. sphinx/util/matching.py +5 -2
  291. sphinx/util/math.py +6 -3
  292. sphinx/util/nodes.py +70 -31
  293. sphinx/util/osutil.py +22 -40
  294. sphinx/util/parallel.py +4 -1
  295. sphinx/util/rst.py +7 -3
  296. sphinx/util/tags.py +11 -4
  297. sphinx/util/template.py +17 -14
  298. sphinx/util/typing.py +61 -20
  299. sphinx/versioning.py +6 -4
  300. sphinx/writers/html.py +1 -1
  301. sphinx/writers/html5.py +32 -24
  302. sphinx/writers/latex.py +67 -53
  303. sphinx/writers/manpage.py +9 -5
  304. sphinx/writers/texinfo.py +11 -9
  305. sphinx/writers/text.py +14 -9
  306. sphinx/writers/xml.py +3 -2
  307. {sphinx-7.1.2.dist-info → sphinx-7.2.0.dist-info}/METADATA +7 -5
  308. sphinx-7.2.0.dist-info/RECORD +568 -0
  309. sphinx/testing/comparer.py +0 -97
  310. sphinx-7.1.2.dist-info/RECORD +0 -564
  311. {sphinx-7.1.2.dist-info → sphinx-7.2.0.dist-info}/LICENSE +0 -0
  312. {sphinx-7.1.2.dist-info → sphinx-7.2.0.dist-info}/WHEEL +0 -0
  313. {sphinx-7.1.2.dist-info → sphinx-7.2.0.dist-info}/entry_points.txt +0 -0
sphinx/search/de.py CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Dict
5
+ from typing import TYPE_CHECKING, Dict
6
6
 
7
7
  import snowballstemmer
8
8
 
sphinx/search/en.py CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Dict
5
+ from typing import TYPE_CHECKING, Dict
6
6
 
7
7
  import snowballstemmer
8
8
 
sphinx/search/es.py CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Dict
5
+ from typing import TYPE_CHECKING, Dict
6
6
 
7
7
  import snowballstemmer
8
8
 
sphinx/search/fi.py CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Dict
5
+ from typing import TYPE_CHECKING, Dict
6
6
 
7
7
  import snowballstemmer
8
8
 
sphinx/search/fr.py CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Dict
5
+ from typing import TYPE_CHECKING, Dict
6
6
 
7
7
  import snowballstemmer
8
8
 
sphinx/search/hu.py CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Dict
5
+ from typing import TYPE_CHECKING, Dict
6
6
 
7
7
  import snowballstemmer
8
8
 
sphinx/search/it.py CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Dict
5
+ from typing import TYPE_CHECKING, Dict
6
6
 
7
7
  import snowballstemmer
8
8
 
sphinx/search/ja.py CHANGED
@@ -13,7 +13,7 @@ from __future__ import annotations
13
13
  import os
14
14
  import re
15
15
  import sys
16
- from typing import Any, Dict, List
16
+ from typing import TYPE_CHECKING, Any, Dict, List
17
17
 
18
18
  try:
19
19
  import MeCab
sphinx/search/nl.py CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Dict
5
+ from typing import TYPE_CHECKING, Dict
6
6
 
7
7
  import snowballstemmer
8
8
 
sphinx/search/no.py CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Dict
5
+ from typing import TYPE_CHECKING, Dict
6
6
 
7
7
  import snowballstemmer
8
8
 
sphinx/search/pt.py CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Dict
5
+ from typing import TYPE_CHECKING, Dict
6
6
 
7
7
  import snowballstemmer
8
8
 
sphinx/search/ro.py CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Dict, Set
5
+ from typing import TYPE_CHECKING, Dict, Set
6
6
 
7
7
  import snowballstemmer
8
8
 
sphinx/search/ru.py CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Dict
5
+ from typing import TYPE_CHECKING, Dict
6
6
 
7
7
  import snowballstemmer
8
8
 
sphinx/search/sv.py CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Dict
5
+ from typing import TYPE_CHECKING, Dict
6
6
 
7
7
  import snowballstemmer
8
8
 
sphinx/search/tr.py CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Dict, Set
5
+ from typing import TYPE_CHECKING, Dict, Set
6
6
 
7
7
  import snowballstemmer
8
8
 
sphinx/search/zh.py CHANGED
@@ -4,7 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  import os
6
6
  import re
7
- from typing import Dict, List
7
+ from typing import TYPE_CHECKING, Dict, List
8
8
 
9
9
  import snowballstemmer
10
10
 
@@ -2,17 +2,21 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import shutil
5
6
  import subprocess
6
7
  import sys
7
8
  from collections import namedtuple
8
9
  from io import StringIO
9
- from typing import Any, Callable, Generator
10
+ from typing import TYPE_CHECKING, Any, Callable
10
11
 
11
12
  import pytest
12
13
 
13
- from sphinx.testing import util
14
14
  from sphinx.testing.util import SphinxTestApp, SphinxTestAppWrapperForSkipBuilding
15
15
 
16
+ if TYPE_CHECKING:
17
+ from collections.abc import Generator
18
+ from pathlib import Path
19
+
16
20
  DEFAULT_ENABLED_MARKERS = [
17
21
  (
18
22
  'sphinx(builder, testroot=None, freshenv=False, confoverrides=None, tags=None,'
@@ -57,7 +61,7 @@ class SharedResult:
57
61
 
58
62
  @pytest.fixture()
59
63
  def app_params(request: Any, test_params: dict, shared_result: SharedResult,
60
- sphinx_test_tempdir: str, rootdir: str) -> tuple[dict, dict]:
64
+ sphinx_test_tempdir: str, rootdir: str) -> _app_params:
61
65
  """
62
66
  Parameters that are specified by 'pytest.mark.sphinx' for
63
67
  sphinx.application.Sphinx initialization
@@ -79,8 +83,8 @@ def app_params(request: Any, test_params: dict, shared_result: SharedResult,
79
83
  # ##### process pytest.mark.test_params
80
84
  if test_params['shared_result']:
81
85
  if 'srcdir' in kwargs:
82
- raise pytest.Exception('You can not specify shared_result and '
83
- 'srcdir in same time.')
86
+ msg = 'You can not specify shared_result and srcdir in same time.'
87
+ raise pytest.Exception(msg)
84
88
  kwargs['srcdir'] = test_params['shared_result']
85
89
  restore = shared_result.restore(test_params['shared_result'])
86
90
  kwargs.update(restore)
@@ -93,9 +97,12 @@ def app_params(request: Any, test_params: dict, shared_result: SharedResult,
93
97
  # special support for sphinx/tests
94
98
  if rootdir and not srcdir.exists():
95
99
  testroot_path = rootdir / ('test-' + testroot)
96
- testroot_path.copytree(srcdir)
100
+ shutil.copytree(testroot_path, srcdir)
101
+
102
+ return _app_params(args, kwargs)
97
103
 
98
- return namedtuple('app_params', 'args,kwargs')(args, kwargs) # type: ignore
104
+
105
+ _app_params = namedtuple('_app_params', 'args,kwargs')
99
106
 
100
107
 
101
108
  @pytest.fixture()
@@ -116,13 +123,13 @@ def test_params(request: Any) -> dict:
116
123
  }
117
124
  result.update(kwargs)
118
125
 
119
- if (result['shared_result'] and not isinstance(result['shared_result'], str)):
120
- raise pytest.Exception('You can only provide a string type of value '
121
- 'for "shared_result" ')
126
+ if result['shared_result'] and not isinstance(result['shared_result'], str):
127
+ msg = 'You can only provide a string type of value for "shared_result"'
128
+ raise pytest.Exception(msg)
122
129
  return result
123
130
 
124
131
 
125
- @pytest.fixture(scope='function')
132
+ @pytest.fixture()
126
133
  def app(test_params: dict, app_params: tuple[dict, dict], make_app: Callable,
127
134
  shared_result: SharedResult) -> Generator[SphinxTestApp, None, None]:
128
135
  """
@@ -143,7 +150,7 @@ def app(test_params: dict, app_params: tuple[dict, dict], make_app: Callable,
143
150
  shared_result.store(test_params['shared_result'], app_)
144
151
 
145
152
 
146
- @pytest.fixture(scope='function')
153
+ @pytest.fixture()
147
154
  def status(app: SphinxTestApp) -> StringIO:
148
155
  """
149
156
  Back-compatibility for testing with previous @with_app decorator
@@ -151,7 +158,7 @@ def status(app: SphinxTestApp) -> StringIO:
151
158
  return app._status
152
159
 
153
160
 
154
- @pytest.fixture(scope='function')
161
+ @pytest.fixture()
155
162
  def warning(app: SphinxTestApp) -> StringIO:
156
163
  """
157
164
  Back-compatibility for testing with previous @with_app decorator
@@ -166,8 +173,6 @@ def make_app(test_params: dict, monkeypatch: Any) -> Generator[Callable, None, N
166
173
  if you want to initialize 'app' in your test function. please use this
167
174
  instead of using SphinxTestApp class directory.
168
175
  """
169
- monkeypatch.setattr('sphinx.application.abspath', lambda x: x)
170
-
171
176
  apps = []
172
177
  syspath = sys.path[:]
173
178
 
@@ -215,21 +220,9 @@ def if_graphviz_found(app: SphinxTestApp) -> None: # NoQA: PT004
215
220
 
216
221
 
217
222
  @pytest.fixture(scope='session')
218
- def sphinx_test_tempdir(tmpdir_factory: Any) -> util.path:
219
- """
220
- Temporary directory wrapped with `path` class.
221
- """
222
- tmpdir = tmpdir_factory.getbasetemp()
223
- return util.path(tmpdir).abspath()
224
-
225
-
226
- @pytest.fixture()
227
- def tempdir(tmpdir: str) -> util.path:
228
- """
229
- Temporary directory wrapped with `path` class.
230
- This fixture is for back-compatibility with old test implementation.
231
- """
232
- return util.path(tmpdir)
223
+ def sphinx_test_tempdir(tmp_path_factory: Any) -> Path:
224
+ """Temporary directory."""
225
+ return tmp_path_factory.getbasetemp()
233
226
 
234
227
 
235
228
  @pytest.fixture()
sphinx/testing/path.py CHANGED
@@ -3,11 +3,18 @@ from __future__ import annotations
3
3
  import os
4
4
  import shutil
5
5
  import sys
6
+ import warnings
6
7
  from typing import IO, TYPE_CHECKING, Any, Callable
7
8
 
9
+ from sphinx.deprecation import RemovedInSphinx90Warning
10
+
8
11
  if TYPE_CHECKING:
9
12
  import builtins
10
13
 
14
+ warnings.warn("'sphinx.testing.path' is deprecated. "
15
+ "Use 'os.path' or 'pathlib' instead.",
16
+ RemovedInSphinx90Warning, stacklevel=2)
17
+
11
18
  FILESYSTEMENCODING = sys.getfilesystemencoding() or sys.getdefaultencoding()
12
19
 
13
20
 
@@ -27,6 +34,8 @@ class path(str):
27
34
  Represents a path which behaves like a string.
28
35
  """
29
36
 
37
+ __slots__ = ()
38
+
30
39
  @property
31
40
  def parent(self) -> path:
32
41
  """
@@ -18,10 +18,18 @@ def parse(app: Sphinx, text: str, docname: str = 'index') -> nodes.document:
18
18
  parser = RSTParser()
19
19
  parser.set_application(app)
20
20
  with sphinx_domains(app.env):
21
- return publish_doctree(text, path.join(app.srcdir, docname + '.rst'),
22
- reader=reader,
23
- parser=parser,
24
- settings_overrides={'env': app.env,
25
- 'gettext_compact': True})
21
+ return publish_doctree(
22
+ text,
23
+ path.join(app.srcdir, docname + '.rst'),
24
+ reader=reader,
25
+ parser=parser,
26
+ settings_overrides={
27
+ 'env': app.env,
28
+ 'gettext_compact': True,
29
+ 'input_encoding': 'utf-8',
30
+ 'output_encoding': 'unicode',
31
+ 'traceback': True,
32
+ },
33
+ )
26
34
  finally:
27
35
  app.env.temp_data.pop('docname', None)
sphinx/testing/util.py CHANGED
@@ -1,44 +1,27 @@
1
1
  """Sphinx test suite utilities"""
2
2
  from __future__ import annotations
3
3
 
4
- import functools
4
+ import contextlib
5
5
  import os
6
6
  import re
7
7
  import sys
8
8
  import warnings
9
- from typing import IO, TYPE_CHECKING, Any, Generator
9
+ from typing import IO, TYPE_CHECKING, Any
10
10
  from xml.etree import ElementTree
11
11
 
12
12
  from docutils import nodes
13
- from docutils.nodes import Node
14
13
  from docutils.parsers.rst import directives, roles
15
14
 
16
15
  from sphinx import application, locale
17
16
  from sphinx.pycode import ModuleAnalyzer
18
- from sphinx.testing.path import path
19
- from sphinx.util.osutil import relpath
20
17
 
21
18
  if TYPE_CHECKING:
22
19
  from io import StringIO
20
+ from pathlib import Path
23
21
 
24
- __all__ = [
25
- 'Struct', 'SphinxTestApp', 'SphinxTestAppWrapperForSkipBuilding',
26
- ]
22
+ from docutils.nodes import Node
27
23
 
28
-
29
- def assert_re_search(regex: re.Pattern, text: str, flags: int = 0) -> None:
30
- if not re.search(regex, text, flags):
31
- raise AssertionError(f'{regex!r} did not match {text!r}')
32
-
33
-
34
- def assert_not_re_search(regex: re.Pattern, text: str, flags: int = 0) -> None:
35
- if re.search(regex, text, flags):
36
- raise AssertionError(f'{regex!r} did match {text!r}')
37
-
38
-
39
- def assert_startswith(thing: str, prefix: str) -> None:
40
- if not thing.startswith(prefix):
41
- raise AssertionError(f'{thing!r} does not start with {prefix!r}')
24
+ __all__ = 'SphinxTestApp', 'SphinxTestAppWrapperForSkipBuilding'
42
25
 
43
26
 
44
27
  def assert_node(node: Node, cls: Any = None, xpath: str = "", **kwargs: Any) -> None:
@@ -73,8 +56,10 @@ def assert_node(node: Node, cls: Any = None, xpath: str = "", **kwargs: Any) ->
73
56
  'The node%s does not have any attributes' % xpath
74
57
 
75
58
  for key, value in kwargs.items():
76
- assert key in node, \
77
- f'The node{xpath} does not have {key!r} attribute: {node!r}'
59
+ if key not in node:
60
+ if (key := key.replace('_', '-')) not in node:
61
+ msg = f'The node{xpath} does not have {key!r} attribute: {node!r}'
62
+ raise AssertionError(msg)
78
63
  assert node[key] == value, \
79
64
  f'The node{xpath}[{key}] is not {value!r}: {node[key]!r}'
80
65
 
@@ -85,11 +70,6 @@ def etree_parse(path: str) -> Any:
85
70
  return ElementTree.parse(path) # NoQA: S314 # using known data in tests
86
71
 
87
72
 
88
- class Struct:
89
- def __init__(self, **kwargs: Any) -> None:
90
- self.__dict__.update(kwargs)
91
-
92
-
93
73
  class SphinxTestApp(application.Sphinx):
94
74
  """
95
75
  A subclass of :class:`Sphinx` that runs on the test root, with some
@@ -101,8 +81,8 @@ class SphinxTestApp(application.Sphinx):
101
81
  def __init__(
102
82
  self,
103
83
  buildername: str = 'html',
104
- srcdir: path | None = None,
105
- builddir: path | None = None,
84
+ srcdir: Path | None = None,
85
+ builddir: Path | None = None,
106
86
  freshenv: bool = False,
107
87
  confoverrides: dict | None = None,
108
88
  status: IO | None = None,
@@ -115,23 +95,23 @@ class SphinxTestApp(application.Sphinx):
115
95
 
116
96
  self.docutils_conf_path = srcdir / 'docutils.conf'
117
97
  if docutilsconf is not None:
118
- self.docutils_conf_path.write_text(docutilsconf)
98
+ self.docutils_conf_path.write_text(docutilsconf, encoding='utf8')
119
99
 
120
100
  if builddir is None:
121
101
  builddir = srcdir / '_build'
122
102
 
123
103
  confdir = srcdir
124
104
  outdir = builddir.joinpath(buildername)
125
- outdir.makedirs(exist_ok=True)
105
+ outdir.mkdir(parents=True, exist_ok=True)
126
106
  doctreedir = builddir.joinpath('doctrees')
127
- doctreedir.makedirs(exist_ok=True)
107
+ doctreedir.mkdir(parents=True, exist_ok=True)
128
108
  if confoverrides is None:
129
109
  confoverrides = {}
130
110
  warningiserror = False
131
111
 
132
112
  self._saved_path = sys.path[:]
133
- self._saved_directives = directives._directives.copy() # type: ignore
134
- self._saved_roles = roles._roles.copy() # type: ignore
113
+ self._saved_directives = directives._directives.copy() # type: ignore[attr-defined]
114
+ self._saved_roles = roles._roles.copy() # type: ignore[attr-defined]
135
115
 
136
116
  self._saved_nodeclasses = {v for v in dir(nodes.GenericNodeVisitor)
137
117
  if v.startswith('visit_')}
@@ -149,17 +129,15 @@ class SphinxTestApp(application.Sphinx):
149
129
  locale.translators.clear()
150
130
  sys.path[:] = self._saved_path
151
131
  sys.modules.pop('autodoc_fodder', None)
152
- directives._directives = self._saved_directives # type: ignore
153
- roles._roles = self._saved_roles # type: ignore
132
+ directives._directives = self._saved_directives # type: ignore[attr-defined]
133
+ roles._roles = self._saved_roles # type: ignore[attr-defined]
154
134
  for method in dir(nodes.GenericNodeVisitor):
155
135
  if method.startswith('visit_') and \
156
136
  method not in self._saved_nodeclasses:
157
137
  delattr(nodes.GenericNodeVisitor, 'visit_' + method[6:])
158
138
  delattr(nodes.GenericNodeVisitor, 'depart_' + method[6:])
159
- try:
139
+ with contextlib.suppress(FileNotFoundError):
160
140
  os.remove(self.docutils_conf_path)
161
- except FileNotFoundError:
162
- pass
163
141
 
164
142
  def __repr__(self) -> str:
165
143
  return f'<{self.__class__.__name__} buildername={self.builder.name!r}>'
@@ -183,32 +161,11 @@ class SphinxTestAppWrapperForSkipBuilding:
183
161
  return getattr(self.app, name)
184
162
 
185
163
  def build(self, *args: Any, **kwargs: Any) -> None:
186
- if not self.app.outdir.listdir(): # type: ignore
164
+ if not os.listdir(self.app.outdir):
187
165
  # if listdir is empty, do build.
188
166
  self.app.build(*args, **kwargs)
189
167
  # otherwise, we can use built cache
190
168
 
191
169
 
192
- _unicode_literals_re = re.compile(r'u(".*?")|u(\'.*?\')')
193
-
194
-
195
- def find_files(root: str, suffix: str | None = None) -> Generator[str, None, None]:
196
- for dirpath, _dirs, files in os.walk(root, followlinks=True):
197
- dirpath = path(dirpath)
198
- for f in [f for f in files if not suffix or f.endswith(suffix)]:
199
- fpath = dirpath / f
200
- yield relpath(fpath, root)
201
-
202
-
203
170
  def strip_escseq(text: str) -> str:
204
171
  return re.sub('\x1b.*?m', '', text)
205
-
206
-
207
- def simple_decorator(f):
208
- """
209
- A simple decorator that does nothing, for tests to use.
210
- """
211
- @functools.wraps(f)
212
- def wrapper(*args, **kwargs):
213
- return f(*args, **kwargs)
214
- return wrapper
@@ -310,22 +310,22 @@
310
310
  \newcommand{\optionlistlabel}[1]{\normalfont\bfseries #1 \hfill}% \bf deprecated
311
311
  \newenvironment{optionlist}[1]
312
312
  {\begin{list}{}
313
- {\setlength{\labelwidth}{#1}
314
- \setlength{\rightmargin}{1cm}
315
- \setlength{\leftmargin}{\rightmargin}
316
- \addtolength{\leftmargin}{\labelwidth}
317
- \addtolength{\leftmargin}{\labelsep}
318
- \renewcommand{\makelabel}{\optionlistlabel}}
313
+ {\setlength{\labelwidth}{#1}%
314
+ \setlength{\rightmargin}{1cm}%
315
+ \setlength{\leftmargin}{\rightmargin}%
316
+ \addtolength{\leftmargin}{\labelwidth}%
317
+ \addtolength{\leftmargin}{\labelsep}%
318
+ \renewcommand{\makelabel}{\optionlistlabel}}%
319
319
  }{\end{list}}
320
320
 
321
321
  \newlength{\lineblockindentation}
322
322
  \setlength{\lineblockindentation}{2.5em}
323
323
  \newenvironment{lineblock}[1]
324
324
  {\begin{list}{}
325
- {\setlength{\partopsep}{\parskip}
326
- \addtolength{\partopsep}{\baselineskip}
325
+ {\setlength{\partopsep}{\parskip}%
326
+ \addtolength{\partopsep}{\baselineskip}%
327
327
  \topsep0pt\itemsep0.15\baselineskip\parsep0pt
328
- \leftmargin#1\relax}
328
+ \leftmargin#1\relax}%
329
329
  \raggedright}
330
330
  {\end{list}}
331
331
 
@@ -351,12 +351,12 @@
351
351
  \DUprovidelength{\DUlineblockindent}{2.5em}
352
352
  \ifdefined\DUlineblock\else
353
353
  \newenvironment{DUlineblock}[1]{%
354
- \list{}{\setlength{\partopsep}{\parskip}
355
- \addtolength{\partopsep}{\baselineskip}
356
- \setlength{\topsep}{0pt}
357
- \setlength{\itemsep}{0.15\baselineskip}
358
- \setlength{\parsep}{0pt}
359
- \setlength{\leftmargin}{#1}}
354
+ \list{}{\setlength{\partopsep}{\parskip}%
355
+ \addtolength{\partopsep}{\baselineskip}%
356
+ \setlength{\topsep}{0pt}%
357
+ \setlength{\itemsep}{0.15\baselineskip}%
358
+ \setlength{\parsep}{0pt}%
359
+ \setlength{\leftmargin}{#1}}%
360
360
  \raggedright
361
361
  }
362
362
  {\endlist}
@@ -19,6 +19,10 @@ body {
19
19
  line-height: 1.4em;
20
20
  color: black;
21
21
  background-color: {{ theme_bgcolor }};
22
+
23
+ /* fix for background colors breaking at horizontal
24
+ scrolling on smaller devices */
25
+ min-width: fit-content;
22
26
  }
23
27
 
24
28
 
@@ -41,6 +45,10 @@ a {
41
45
  color: {{ theme_linkcolor }};
42
46
  }
43
47
 
48
+ a:visited {
49
+ color: #551a8b;
50
+ }
51
+
44
52
  div.bodywrapper a, div.footer a {
45
53
  text-decoration: underline;
46
54
  }
@@ -127,8 +135,7 @@ dt:target, .highlighted {
127
135
  /* Header */
128
136
 
129
137
  div.header {
130
- padding-top: 10px;
131
- padding-bottom: 10px;
138
+ padding: 1em;
132
139
  }
133
140
 
134
141
  div.header .headertitle {
@@ -165,8 +172,7 @@ img.logo {
165
172
  /* Content */
166
173
  div.content-wrapper {
167
174
  background-color: white;
168
- padding-top: 20px;
169
- padding-bottom: 20px;
175
+ padding: 1em;
170
176
  }
171
177
 
172
178
  div.document {
@@ -102,7 +102,7 @@
102
102
  {%- if html_tag %}
103
103
  {{ html_tag }}
104
104
  {%- else %}
105
- <html{% if language is not none %} lang="{{ language }}"{% endif %}>
105
+ <html{% if language is not none %} lang="{{ language }}"{% endif %} data-content_root="{{ content_root }}">
106
106
  {%- endif %}
107
107
  <head>
108
108
  <meta charset="{{ encoding }}" />
@@ -237,6 +237,10 @@ a.headerlink {
237
237
  visibility: hidden;
238
238
  }
239
239
 
240
+ a:visited {
241
+ color: #551A8B;
242
+ }
243
+
240
244
  h1:hover > a.headerlink,
241
245
  h2:hover > a.headerlink,
242
246
  h3:hover > a.headerlink,
@@ -1,5 +1,4 @@
1
- var DOCUMENTATION_OPTIONS = {
2
- URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
1
+ const DOCUMENTATION_OPTIONS = {
3
2
  VERSION: '{{ release|e }}',
4
3
  LANGUAGE: '{{ language }}',
5
4
  COLLAPSE_INDEX: false,