Sphinx 7.2.5__py3-none-any.whl → 7.3.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 (388) hide show
  1. sphinx/__init__.py +8 -9
  2. sphinx/addnodes.py +31 -28
  3. sphinx/application.py +9 -15
  4. sphinx/builders/__init__.py +5 -6
  5. sphinx/builders/_epub_base.py +17 -9
  6. sphinx/builders/changes.py +10 -5
  7. sphinx/builders/dirhtml.py +4 -2
  8. sphinx/builders/dummy.py +3 -2
  9. sphinx/builders/epub3.py +5 -3
  10. sphinx/builders/gettext.py +24 -7
  11. sphinx/builders/html/__init__.py +88 -96
  12. sphinx/builders/html/_assets.py +16 -16
  13. sphinx/builders/html/transforms.py +4 -2
  14. sphinx/builders/latex/__init__.py +40 -33
  15. sphinx/builders/latex/nodes.py +6 -2
  16. sphinx/builders/latex/transforms.py +17 -8
  17. sphinx/builders/latex/util.py +1 -1
  18. sphinx/builders/linkcheck.py +86 -27
  19. sphinx/builders/manpage.py +8 -6
  20. sphinx/builders/singlehtml.py +5 -4
  21. sphinx/builders/texinfo.py +18 -14
  22. sphinx/builders/text.py +3 -2
  23. sphinx/builders/xml.py +5 -2
  24. sphinx/cmd/build.py +119 -76
  25. sphinx/cmd/make_mode.py +21 -20
  26. sphinx/cmd/quickstart.py +13 -16
  27. sphinx/config.py +432 -250
  28. sphinx/deprecation.py +23 -13
  29. sphinx/directives/__init__.py +8 -8
  30. sphinx/directives/code.py +7 -7
  31. sphinx/directives/other.py +23 -13
  32. sphinx/directives/patches.py +7 -6
  33. sphinx/domains/__init__.py +2 -2
  34. sphinx/domains/c/__init__.py +796 -0
  35. sphinx/domains/c/_ast.py +1421 -0
  36. sphinx/domains/c/_ids.py +65 -0
  37. sphinx/domains/c/_parser.py +1048 -0
  38. sphinx/domains/c/_symbol.py +700 -0
  39. sphinx/domains/changeset.py +11 -7
  40. sphinx/domains/citation.py +5 -2
  41. sphinx/domains/cpp/__init__.py +1089 -0
  42. sphinx/domains/cpp/_ast.py +3635 -0
  43. sphinx/domains/cpp/_ids.py +537 -0
  44. sphinx/domains/cpp/_parser.py +2117 -0
  45. sphinx/domains/cpp/_symbol.py +1092 -0
  46. sphinx/domains/index.py +6 -4
  47. sphinx/domains/javascript.py +16 -13
  48. sphinx/domains/math.py +9 -4
  49. sphinx/domains/python/__init__.py +890 -0
  50. sphinx/domains/python/_annotations.py +507 -0
  51. sphinx/domains/python/_object.py +426 -0
  52. sphinx/domains/rst.py +12 -7
  53. sphinx/domains/{std.py → std/__init__.py} +19 -16
  54. sphinx/environment/__init__.py +21 -19
  55. sphinx/environment/adapters/indexentries.py +2 -2
  56. sphinx/environment/adapters/toctree.py +10 -9
  57. sphinx/environment/collectors/__init__.py +6 -3
  58. sphinx/environment/collectors/asset.py +4 -3
  59. sphinx/environment/collectors/dependencies.py +3 -2
  60. sphinx/environment/collectors/metadata.py +6 -5
  61. sphinx/environment/collectors/title.py +3 -2
  62. sphinx/environment/collectors/toctree.py +5 -4
  63. sphinx/errors.py +13 -2
  64. sphinx/events.py +14 -9
  65. sphinx/ext/apidoc.py +9 -11
  66. sphinx/ext/autodoc/__init__.py +105 -71
  67. sphinx/ext/autodoc/directive.py +7 -6
  68. sphinx/ext/autodoc/importer.py +132 -52
  69. sphinx/ext/autodoc/mock.py +7 -5
  70. sphinx/ext/autodoc/preserve_defaults.py +4 -3
  71. sphinx/ext/autodoc/type_comment.py +2 -1
  72. sphinx/ext/autodoc/typehints.py +5 -4
  73. sphinx/ext/autosectionlabel.py +3 -2
  74. sphinx/ext/autosummary/__init__.py +21 -17
  75. sphinx/ext/autosummary/generate.py +9 -9
  76. sphinx/ext/coverage.py +26 -20
  77. sphinx/ext/doctest.py +38 -33
  78. sphinx/ext/duration.py +1 -0
  79. sphinx/ext/extlinks.py +4 -3
  80. sphinx/ext/githubpages.py +3 -2
  81. sphinx/ext/graphviz.py +10 -7
  82. sphinx/ext/ifconfig.py +5 -5
  83. sphinx/ext/imgconverter.py +6 -5
  84. sphinx/ext/imgmath.py +9 -8
  85. sphinx/ext/inheritance_diagram.py +31 -31
  86. sphinx/ext/intersphinx.py +140 -23
  87. sphinx/ext/linkcode.py +3 -2
  88. sphinx/ext/mathjax.py +2 -1
  89. sphinx/ext/napoleon/__init__.py +12 -7
  90. sphinx/ext/napoleon/docstring.py +34 -32
  91. sphinx/ext/todo.py +10 -7
  92. sphinx/ext/viewcode.py +12 -11
  93. sphinx/extension.py +18 -8
  94. sphinx/highlighting.py +39 -20
  95. sphinx/io.py +17 -8
  96. sphinx/jinja2glue.py +16 -15
  97. sphinx/locale/__init__.py +30 -23
  98. sphinx/locale/ar/LC_MESSAGES/sphinx.mo +0 -0
  99. sphinx/locale/ar/LC_MESSAGES/sphinx.po +818 -761
  100. sphinx/locale/bg/LC_MESSAGES/sphinx.mo +0 -0
  101. sphinx/locale/bg/LC_MESSAGES/sphinx.po +811 -754
  102. sphinx/locale/bn/LC_MESSAGES/sphinx.mo +0 -0
  103. sphinx/locale/bn/LC_MESSAGES/sphinx.po +835 -778
  104. sphinx/locale/ca/LC_MESSAGES/sphinx.mo +0 -0
  105. sphinx/locale/ca/LC_MESSAGES/sphinx.po +864 -807
  106. sphinx/locale/cak/LC_MESSAGES/sphinx.mo +0 -0
  107. sphinx/locale/cak/LC_MESSAGES/sphinx.po +816 -759
  108. sphinx/locale/cs/LC_MESSAGES/sphinx.mo +0 -0
  109. sphinx/locale/cs/LC_MESSAGES/sphinx.po +837 -780
  110. sphinx/locale/cy/LC_MESSAGES/sphinx.mo +0 -0
  111. sphinx/locale/cy/LC_MESSAGES/sphinx.po +819 -762
  112. sphinx/locale/da/LC_MESSAGES/sphinx.mo +0 -0
  113. sphinx/locale/da/LC_MESSAGES/sphinx.po +838 -781
  114. sphinx/locale/de/LC_MESSAGES/sphinx.mo +0 -0
  115. sphinx/locale/de/LC_MESSAGES/sphinx.po +838 -781
  116. sphinx/locale/de_DE/LC_MESSAGES/sphinx.mo +0 -0
  117. sphinx/locale/de_DE/LC_MESSAGES/sphinx.po +811 -754
  118. sphinx/locale/el/LC_MESSAGES/sphinx.mo +0 -0
  119. sphinx/locale/el/LC_MESSAGES/sphinx.po +853 -796
  120. sphinx/locale/en_DE/LC_MESSAGES/sphinx.mo +0 -0
  121. sphinx/locale/en_DE/LC_MESSAGES/sphinx.po +811 -754
  122. sphinx/locale/en_FR/LC_MESSAGES/sphinx.mo +0 -0
  123. sphinx/locale/en_FR/LC_MESSAGES/sphinx.po +811 -754
  124. sphinx/locale/en_GB/LC_MESSAGES/sphinx.mo +0 -0
  125. sphinx/locale/en_GB/LC_MESSAGES/sphinx.po +856 -799
  126. sphinx/locale/en_HK/LC_MESSAGES/sphinx.mo +0 -0
  127. sphinx/locale/en_HK/LC_MESSAGES/sphinx.po +811 -754
  128. sphinx/locale/eo/LC_MESSAGES/sphinx.mo +0 -0
  129. sphinx/locale/eo/LC_MESSAGES/sphinx.po +820 -763
  130. sphinx/locale/es/LC_MESSAGES/sphinx.mo +0 -0
  131. sphinx/locale/es/LC_MESSAGES/sphinx.po +856 -799
  132. sphinx/locale/es_CO/LC_MESSAGES/sphinx.mo +0 -0
  133. sphinx/locale/es_CO/LC_MESSAGES/sphinx.po +811 -754
  134. sphinx/locale/et/LC_MESSAGES/sphinx.mo +0 -0
  135. sphinx/locale/et/LC_MESSAGES/sphinx.po +845 -788
  136. sphinx/locale/eu/LC_MESSAGES/sphinx.mo +0 -0
  137. sphinx/locale/eu/LC_MESSAGES/sphinx.po +837 -780
  138. sphinx/locale/fa/LC_MESSAGES/sphinx.mo +0 -0
  139. sphinx/locale/fa/LC_MESSAGES/sphinx.po +854 -797
  140. sphinx/locale/fi/LC_MESSAGES/sphinx.mo +0 -0
  141. sphinx/locale/fi/LC_MESSAGES/sphinx.po +816 -759
  142. sphinx/locale/fr/LC_MESSAGES/sphinx.js +1 -1
  143. sphinx/locale/fr/LC_MESSAGES/sphinx.mo +0 -0
  144. sphinx/locale/fr/LC_MESSAGES/sphinx.po +904 -847
  145. sphinx/locale/fr_FR/LC_MESSAGES/sphinx.mo +0 -0
  146. sphinx/locale/fr_FR/LC_MESSAGES/sphinx.po +811 -754
  147. sphinx/locale/gl/LC_MESSAGES/sphinx.js +54 -54
  148. sphinx/locale/gl/LC_MESSAGES/sphinx.mo +0 -0
  149. sphinx/locale/gl/LC_MESSAGES/sphinx.po +1506 -1449
  150. sphinx/locale/he/LC_MESSAGES/sphinx.js +1 -1
  151. sphinx/locale/he/LC_MESSAGES/sphinx.mo +0 -0
  152. sphinx/locale/he/LC_MESSAGES/sphinx.po +823 -766
  153. sphinx/locale/hi/LC_MESSAGES/sphinx.mo +0 -0
  154. sphinx/locale/hi/LC_MESSAGES/sphinx.po +853 -796
  155. sphinx/locale/hi_IN/LC_MESSAGES/sphinx.mo +0 -0
  156. sphinx/locale/hi_IN/LC_MESSAGES/sphinx.po +811 -754
  157. sphinx/locale/hr/LC_MESSAGES/sphinx.mo +0 -0
  158. sphinx/locale/hr/LC_MESSAGES/sphinx.po +844 -787
  159. sphinx/locale/hu/LC_MESSAGES/sphinx.mo +0 -0
  160. sphinx/locale/hu/LC_MESSAGES/sphinx.po +837 -780
  161. sphinx/locale/id/LC_MESSAGES/sphinx.mo +0 -0
  162. sphinx/locale/id/LC_MESSAGES/sphinx.po +854 -797
  163. sphinx/locale/is/LC_MESSAGES/sphinx.mo +0 -0
  164. sphinx/locale/is/LC_MESSAGES/sphinx.po +811 -754
  165. sphinx/locale/it/LC_MESSAGES/sphinx.mo +0 -0
  166. sphinx/locale/it/LC_MESSAGES/sphinx.po +837 -780
  167. sphinx/locale/ja/LC_MESSAGES/sphinx.mo +0 -0
  168. sphinx/locale/ja/LC_MESSAGES/sphinx.po +853 -796
  169. sphinx/locale/ka/LC_MESSAGES/sphinx.mo +0 -0
  170. sphinx/locale/ka/LC_MESSAGES/sphinx.po +848 -791
  171. sphinx/locale/ko/LC_MESSAGES/sphinx.mo +0 -0
  172. sphinx/locale/ko/LC_MESSAGES/sphinx.po +855 -798
  173. sphinx/locale/lt/LC_MESSAGES/sphinx.mo +0 -0
  174. sphinx/locale/lt/LC_MESSAGES/sphinx.po +837 -780
  175. sphinx/locale/lv/LC_MESSAGES/sphinx.mo +0 -0
  176. sphinx/locale/lv/LC_MESSAGES/sphinx.po +837 -780
  177. sphinx/locale/mk/LC_MESSAGES/sphinx.mo +0 -0
  178. sphinx/locale/mk/LC_MESSAGES/sphinx.po +825 -768
  179. sphinx/locale/nb_NO/LC_MESSAGES/sphinx.js +27 -27
  180. sphinx/locale/nb_NO/LC_MESSAGES/sphinx.mo +0 -0
  181. sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po +876 -818
  182. sphinx/locale/ne/LC_MESSAGES/sphinx.mo +0 -0
  183. sphinx/locale/ne/LC_MESSAGES/sphinx.po +837 -780
  184. sphinx/locale/nl/LC_MESSAGES/sphinx.mo +0 -0
  185. sphinx/locale/nl/LC_MESSAGES/sphinx.po +844 -787
  186. sphinx/locale/pl/LC_MESSAGES/sphinx.mo +0 -0
  187. sphinx/locale/pl/LC_MESSAGES/sphinx.po +845 -788
  188. sphinx/locale/pt/LC_MESSAGES/sphinx.mo +0 -0
  189. sphinx/locale/pt/LC_MESSAGES/sphinx.po +811 -754
  190. sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo +0 -0
  191. sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po +908 -851
  192. sphinx/locale/pt_PT/LC_MESSAGES/sphinx.mo +0 -0
  193. sphinx/locale/pt_PT/LC_MESSAGES/sphinx.po +837 -780
  194. sphinx/locale/ro/LC_MESSAGES/sphinx.mo +0 -0
  195. sphinx/locale/ro/LC_MESSAGES/sphinx.po +837 -780
  196. sphinx/locale/ru/LC_MESSAGES/sphinx.mo +0 -0
  197. sphinx/locale/ru/LC_MESSAGES/sphinx.po +838 -781
  198. sphinx/locale/si/LC_MESSAGES/sphinx.mo +0 -0
  199. sphinx/locale/si/LC_MESSAGES/sphinx.po +823 -766
  200. sphinx/locale/sk/LC_MESSAGES/sphinx.mo +0 -0
  201. sphinx/locale/sk/LC_MESSAGES/sphinx.po +854 -797
  202. sphinx/locale/sl/LC_MESSAGES/sphinx.mo +0 -0
  203. sphinx/locale/sl/LC_MESSAGES/sphinx.po +832 -775
  204. sphinx/locale/sphinx.pot +813 -755
  205. sphinx/locale/sq/LC_MESSAGES/sphinx.js +1 -1
  206. sphinx/locale/sq/LC_MESSAGES/sphinx.mo +0 -0
  207. sphinx/locale/sq/LC_MESSAGES/sphinx.po +865 -808
  208. sphinx/locale/sr/LC_MESSAGES/sphinx.mo +0 -0
  209. sphinx/locale/sr/LC_MESSAGES/sphinx.po +835 -778
  210. sphinx/locale/sr@latin/LC_MESSAGES/sphinx.mo +0 -0
  211. sphinx/locale/sr_RS/LC_MESSAGES/sphinx.mo +0 -0
  212. sphinx/locale/sv/LC_MESSAGES/sphinx.mo +0 -0
  213. sphinx/locale/sv/LC_MESSAGES/sphinx.po +837 -780
  214. sphinx/locale/ta/LC_MESSAGES/sphinx.js +54 -54
  215. sphinx/locale/ta/LC_MESSAGES/sphinx.mo +0 -0
  216. sphinx/locale/ta/LC_MESSAGES/sphinx.po +1530 -1473
  217. sphinx/locale/te/LC_MESSAGES/sphinx.mo +0 -0
  218. sphinx/locale/te/LC_MESSAGES/sphinx.po +811 -754
  219. sphinx/locale/tr/LC_MESSAGES/sphinx.mo +0 -0
  220. sphinx/locale/tr/LC_MESSAGES/sphinx.po +853 -796
  221. sphinx/locale/uk_UA/LC_MESSAGES/sphinx.mo +0 -0
  222. sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po +833 -776
  223. sphinx/locale/ur/LC_MESSAGES/sphinx.mo +0 -0
  224. sphinx/locale/ur/LC_MESSAGES/sphinx.po +811 -754
  225. sphinx/locale/vi/LC_MESSAGES/sphinx.mo +0 -0
  226. sphinx/locale/vi/LC_MESSAGES/sphinx.po +837 -780
  227. sphinx/locale/yue/LC_MESSAGES/sphinx.mo +0 -0
  228. sphinx/locale/yue/LC_MESSAGES/sphinx.po +811 -754
  229. sphinx/locale/zh_CN/LC_MESSAGES/sphinx.mo +0 -0
  230. sphinx/locale/zh_CN/LC_MESSAGES/sphinx.po +855 -798
  231. sphinx/locale/zh_HK/LC_MESSAGES/sphinx.mo +0 -0
  232. sphinx/locale/zh_HK/LC_MESSAGES/sphinx.po +811 -754
  233. sphinx/locale/zh_TW/LC_MESSAGES/sphinx.js +1 -1
  234. sphinx/locale/zh_TW/LC_MESSAGES/sphinx.mo +0 -0
  235. sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po +879 -822
  236. sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.mo +0 -0
  237. sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.po +811 -754
  238. sphinx/parsers.py +7 -5
  239. sphinx/project.py +18 -11
  240. sphinx/pycode/__init__.py +6 -5
  241. sphinx/pycode/ast.py +23 -8
  242. sphinx/pycode/parser.py +6 -5
  243. sphinx/registry.py +12 -6
  244. sphinx/roles.py +103 -57
  245. sphinx/search/__init__.py +17 -18
  246. sphinx/search/da.py +2 -2
  247. sphinx/search/de.py +2 -2
  248. sphinx/search/en.py +1 -1
  249. sphinx/search/es.py +2 -2
  250. sphinx/search/fi.py +2 -2
  251. sphinx/search/fr.py +2 -2
  252. sphinx/search/hu.py +2 -2
  253. sphinx/search/it.py +2 -2
  254. sphinx/search/ja.py +13 -22
  255. sphinx/search/nl.py +2 -2
  256. sphinx/search/no.py +2 -2
  257. sphinx/search/pt.py +2 -2
  258. sphinx/search/ro.py +1 -1
  259. sphinx/search/ru.py +2 -2
  260. sphinx/search/sv.py +2 -2
  261. sphinx/search/tr.py +1 -1
  262. sphinx/search/zh.py +2 -3
  263. sphinx/templates/graphviz/graphviz.css +1 -1
  264. sphinx/testing/fixtures.py +41 -24
  265. sphinx/testing/path.py +1 -1
  266. sphinx/testing/util.py +142 -53
  267. sphinx/texinputs/sphinx.xdy +1 -1
  268. sphinx/texinputs/sphinxlatextables.sty +1 -1
  269. sphinx/texinputs/sphinxpackagesubstitutefont.sty +21 -0
  270. sphinx/themes/agogo/layout.html +4 -4
  271. sphinx/themes/agogo/static/agogo.css_t +1 -1
  272. sphinx/themes/agogo/theme.toml +22 -0
  273. sphinx/themes/basic/defindex.html +1 -1
  274. sphinx/themes/basic/domainindex.html +1 -1
  275. sphinx/themes/basic/genindex-single.html +1 -1
  276. sphinx/themes/basic/genindex-split.html +1 -1
  277. sphinx/themes/basic/genindex.html +1 -1
  278. sphinx/themes/basic/globaltoc.html +1 -1
  279. sphinx/themes/basic/layout.html +1 -1
  280. sphinx/themes/basic/localtoc.html +1 -1
  281. sphinx/themes/basic/page.html +1 -1
  282. sphinx/themes/basic/relations.html +1 -1
  283. sphinx/themes/basic/search.html +5 -20
  284. sphinx/themes/basic/searchbox.html +3 -3
  285. sphinx/themes/basic/searchfield.html +3 -3
  286. sphinx/themes/basic/sourcelink.html +1 -1
  287. sphinx/themes/basic/static/basic.css_t +1 -1
  288. sphinx/themes/basic/static/doctools.js +1 -1
  289. sphinx/themes/basic/static/language_data.js_t +2 -2
  290. sphinx/themes/basic/static/searchtools.js +105 -60
  291. sphinx/themes/basic/theme.toml +23 -0
  292. sphinx/themes/bizstyle/layout.html +1 -6
  293. sphinx/themes/bizstyle/static/bizstyle.css_t +1 -1
  294. sphinx/themes/bizstyle/static/bizstyle.js_t +1 -1
  295. sphinx/themes/bizstyle/static/css3-mediaqueries_src.js +3 -3
  296. sphinx/themes/bizstyle/theme.toml +12 -0
  297. sphinx/themes/classic/layout.html +1 -1
  298. sphinx/themes/classic/static/classic.css_t +1 -1
  299. sphinx/themes/classic/static/sidebar.js_t +1 -1
  300. sphinx/themes/classic/theme.toml +34 -0
  301. sphinx/themes/default/theme.toml +2 -0
  302. sphinx/themes/epub/epub-cover.html +1 -1
  303. sphinx/themes/epub/layout.html +1 -1
  304. sphinx/themes/epub/static/epub.css_t +1 -1
  305. sphinx/themes/epub/theme.toml +10 -0
  306. sphinx/themes/haiku/layout.html +3 -3
  307. sphinx/themes/haiku/static/haiku.css_t +2 -2
  308. sphinx/themes/haiku/theme.toml +16 -0
  309. sphinx/themes/nature/static/nature.css_t +1 -1
  310. sphinx/themes/nature/theme.toml +6 -0
  311. sphinx/themes/nonav/layout.html +1 -1
  312. sphinx/themes/nonav/static/nonav.css_t +1 -1
  313. sphinx/themes/nonav/theme.toml +10 -0
  314. sphinx/themes/pyramid/static/epub.css_t +1 -1
  315. sphinx/themes/pyramid/static/pyramid.css_t +1 -1
  316. sphinx/themes/pyramid/theme.toml +6 -0
  317. sphinx/themes/scrolls/artwork/logo.svg +1 -1
  318. sphinx/themes/scrolls/layout.html +2 -2
  319. sphinx/themes/scrolls/static/scrolls.css_t +1 -1
  320. sphinx/themes/scrolls/theme.toml +15 -0
  321. sphinx/themes/sphinxdoc/static/sphinxdoc.css_t +1 -1
  322. sphinx/themes/sphinxdoc/theme.toml +6 -0
  323. sphinx/themes/traditional/static/traditional.css_t +1 -1
  324. sphinx/themes/traditional/theme.toml +9 -0
  325. sphinx/theming.py +427 -131
  326. sphinx/transforms/__init__.py +21 -24
  327. sphinx/transforms/compact_bullet_list.py +5 -5
  328. sphinx/transforms/i18n.py +30 -28
  329. sphinx/transforms/post_transforms/__init__.py +9 -7
  330. sphinx/transforms/post_transforms/code.py +4 -1
  331. sphinx/transforms/post_transforms/images.py +17 -13
  332. sphinx/transforms/references.py +3 -1
  333. sphinx/util/__init__.py +15 -11
  334. sphinx/util/_io.py +34 -0
  335. sphinx/util/_pathlib.py +23 -18
  336. sphinx/util/build_phase.py +1 -0
  337. sphinx/util/cfamily.py +19 -11
  338. sphinx/util/console.py +101 -21
  339. sphinx/util/display.py +3 -2
  340. sphinx/util/docfields.py +12 -8
  341. sphinx/util/docutils.py +21 -35
  342. sphinx/util/exceptions.py +3 -2
  343. sphinx/util/fileutil.py +5 -5
  344. sphinx/util/http_date.py +9 -2
  345. sphinx/util/i18n.py +40 -9
  346. sphinx/util/inspect.py +317 -245
  347. sphinx/util/inventory.py +22 -5
  348. sphinx/util/logging.py +81 -7
  349. sphinx/util/matching.py +2 -1
  350. sphinx/util/math.py +1 -2
  351. sphinx/util/nodes.py +39 -29
  352. sphinx/util/osutil.py +25 -6
  353. sphinx/util/parallel.py +6 -1
  354. sphinx/util/requests.py +8 -5
  355. sphinx/util/rst.py +8 -6
  356. sphinx/util/tags.py +3 -3
  357. sphinx/util/template.py +8 -3
  358. sphinx/util/typing.py +76 -42
  359. sphinx/versioning.py +6 -2
  360. sphinx/writers/html.py +1 -1
  361. sphinx/writers/html5.py +17 -13
  362. sphinx/writers/latex.py +12 -12
  363. sphinx/writers/manpage.py +13 -7
  364. sphinx/writers/texinfo.py +13 -10
  365. sphinx/writers/text.py +13 -23
  366. sphinx/writers/xml.py +1 -1
  367. sphinx-7.2.5.dist-info/LICENSE → sphinx-7.3.0.dist-info/LICENSE.rst +1 -1
  368. {sphinx-7.2.5.dist-info → sphinx-7.3.0.dist-info}/METADATA +13 -12
  369. sphinx-7.3.0.dist-info/RECORD +581 -0
  370. sphinx/domains/c.py +0 -3906
  371. sphinx/domains/cpp.py +0 -8233
  372. sphinx/domains/python.py +0 -1769
  373. sphinx/themes/agogo/theme.conf +0 -20
  374. sphinx/themes/basic/theme.conf +0 -16
  375. sphinx/themes/bizstyle/theme.conf +0 -10
  376. sphinx/themes/classic/theme.conf +0 -32
  377. sphinx/themes/default/theme.conf +0 -2
  378. sphinx/themes/epub/theme.conf +0 -8
  379. sphinx/themes/haiku/theme.conf +0 -14
  380. sphinx/themes/nature/theme.conf +0 -4
  381. sphinx/themes/nonav/theme.conf +0 -8
  382. sphinx/themes/pyramid/theme.conf +0 -4
  383. sphinx/themes/scrolls/theme.conf +0 -13
  384. sphinx/themes/sphinxdoc/theme.conf +0 -4
  385. sphinx/themes/traditional/theme.conf +0 -7
  386. sphinx-7.2.5.dist-info/RECORD +0 -569
  387. {sphinx-7.2.5.dist-info → sphinx-7.3.0.dist-info}/WHEEL +0 -0
  388. {sphinx-7.2.5.dist-info → sphinx-7.3.0.dist-info}/entry_points.txt +0 -0
@@ -7,6 +7,7 @@ import contextlib
7
7
  import inspect
8
8
  import re
9
9
  from functools import partial
10
+ from itertools import starmap
10
11
  from typing import TYPE_CHECKING, Any, Callable
11
12
 
12
13
  from sphinx.locale import _, __
@@ -14,6 +15,8 @@ from sphinx.util import logging
14
15
  from sphinx.util.typing import get_type_hints, stringify_annotation
15
16
 
16
17
  if TYPE_CHECKING:
18
+ from collections.abc import Iterator
19
+
17
20
  from sphinx.application import Sphinx
18
21
  from sphinx.config import Config as SphinxConfig
19
22
 
@@ -145,7 +148,7 @@ class GoogleDocstring:
145
148
  """
146
149
 
147
150
  _name_rgx = re.compile(r"^\s*((?::(?P<role>\S+):)?`(?P<name>~?[a-zA-Z0-9_.-]+)`|"
148
- r" (?P<name2>~?[a-zA-Z0-9_.-]+))\s*", re.X)
151
+ r" (?P<name2>~?[a-zA-Z0-9_.-]+))\s*", re.VERBOSE)
149
152
 
150
153
  def __init__(
151
154
  self,
@@ -304,19 +307,18 @@ class GoogleDocstring:
304
307
  _type = _convert_type_spec(_type, self._config.napoleon_type_aliases or {})
305
308
 
306
309
  indent = self._get_indent(line) + 1
307
- _descs = [_desc] + self._dedent(self._consume_indented_block(indent))
310
+ _descs = [_desc, *self._dedent(self._consume_indented_block(indent))]
308
311
  _descs = self.__class__(_descs, self._config).lines()
309
312
  return _name, _type, _descs
310
313
 
311
314
  def _consume_fields(self, parse_type: bool = True, prefer_type: bool = False,
312
315
  multiple: bool = False) -> list[tuple[str, str, list[str]]]:
313
316
  self._consume_empty()
314
- fields = []
317
+ fields: list[tuple[str, str, list[str]]] = []
315
318
  while not self._is_section_break():
316
319
  _name, _type, _desc = self._consume_field(parse_type, prefer_type)
317
320
  if multiple and _name:
318
- for name in _name.split(","):
319
- fields.append((name.strip(), _type, _desc))
321
+ fields.extend((name.strip(), _type, _desc) for name in _name.split(","))
320
322
  elif _name or _type or _desc:
321
323
  fields.append((_name, _type, _desc))
322
324
  return fields
@@ -327,7 +329,7 @@ class GoogleDocstring:
327
329
  if not colon or not _desc:
328
330
  _type, _desc = _desc, _type
329
331
  _desc += colon
330
- _descs = [_desc] + self._dedent(self._consume_to_end())
332
+ _descs = [_desc, *self._dedent(self._consume_to_end())]
331
333
  _descs = self.__class__(_descs, self._config).lines()
332
334
  return _type, _descs
333
335
 
@@ -399,15 +401,15 @@ class GoogleDocstring:
399
401
 
400
402
  def _fix_field_desc(self, desc: list[str]) -> list[str]:
401
403
  if self._is_list(desc):
402
- desc = [''] + desc
404
+ desc = ['', *desc]
403
405
  elif desc[0].endswith('::'):
404
406
  desc_block = desc[1:]
405
407
  indent = self._get_indent(desc[0])
406
408
  block_indent = self._get_initial_indent(desc_block)
407
409
  if block_indent > indent:
408
- desc = [''] + desc
410
+ desc = ['', *desc]
409
411
  else:
410
- desc = ['', desc[0]] + self._indent(desc_block, 4)
412
+ desc = ['', desc[0], *self._indent(desc_block, 4)]
411
413
  return desc
412
414
 
413
415
  def _format_admonition(self, admonition: str, lines: list[str]) -> list[str]:
@@ -416,7 +418,7 @@ class GoogleDocstring:
416
418
  return [f'.. {admonition}:: {lines[0].strip()}', '']
417
419
  elif lines:
418
420
  lines = self._indent(self._dedent(lines), 3)
419
- return ['.. %s::' % admonition, ''] + lines + ['']
421
+ return ['.. %s::' % admonition, '', *lines, '']
420
422
  else:
421
423
  return ['.. %s::' % admonition, '']
422
424
 
@@ -453,7 +455,7 @@ class GoogleDocstring:
453
455
 
454
456
  if _type:
455
457
  lines.append(f':{type_role} {_name}: {_type}')
456
- return lines + ['']
458
+ return [*lines, '']
457
459
 
458
460
  def _format_field(self, _name: str, _type: str, _desc: list[str]) -> list[str]:
459
461
  _desc = self._strip_empty(_desc)
@@ -480,7 +482,7 @@ class GoogleDocstring:
480
482
  if _desc[0]:
481
483
  return [field + _desc[0]] + _desc[1:]
482
484
  else:
483
- return [field] + _desc
485
+ return [field, *_desc]
484
486
  else:
485
487
  return [field]
486
488
 
@@ -537,7 +539,7 @@ class GoogleDocstring:
537
539
  return [(' ' * n) + line for line in lines]
538
540
 
539
541
  def _is_indented(self, line: str, indent: int = 1) -> bool:
540
- for i, s in enumerate(line): # noqa: SIM110
542
+ for i, s in enumerate(line): # NoQA: SIM110
541
543
  if i >= indent:
542
544
  return True
543
545
  elif not s.isspace():
@@ -623,7 +625,7 @@ class GoogleDocstring:
623
625
  self._is_in_section = True
624
626
  self._section_indent = self._get_current_indent()
625
627
  if _directive_regex.match(section):
626
- lines = [section] + self._consume_to_next_section()
628
+ lines = [section, *self._consume_to_next_section()]
627
629
  else:
628
630
  lines = self._sections[section.lower()](section)
629
631
  finally:
@@ -711,7 +713,7 @@ class GoogleDocstring:
711
713
  else:
712
714
  header = '.. rubric:: %s' % section
713
715
  if lines:
714
- return [header, ''] + lines + ['']
716
+ return [header, '', *lines, '']
715
717
  else:
716
718
  return [header, '']
717
719
 
@@ -733,7 +735,7 @@ class GoogleDocstring:
733
735
  if 'no-index' in self._opt or 'noindex' in self._opt:
734
736
  lines.append(' :no-index:')
735
737
  if _desc:
736
- lines.extend([''] + self._indent(_desc, 3))
738
+ lines.extend(['', *self._indent(_desc, 3)])
737
739
  lines.append('')
738
740
  return lines
739
741
 
@@ -888,7 +890,7 @@ def _recombine_set_tokens(tokens: list[str]) -> list[str]:
888
890
  token_queue = collections.deque(tokens)
889
891
  keywords = ("optional", "default")
890
892
 
891
- def takewhile_set(tokens):
893
+ def takewhile_set(tokens: collections.deque[str]) -> Iterator[str]:
892
894
  open_braces = 0
893
895
  previous_token = None
894
896
  while True:
@@ -924,7 +926,7 @@ def _recombine_set_tokens(tokens: list[str]) -> list[str]:
924
926
  if open_braces == 0:
925
927
  break
926
928
 
927
- def combine_set(tokens):
929
+ def combine_set(tokens: collections.deque[str]) -> Iterator[str]:
928
930
  while True:
929
931
  try:
930
932
  token = tokens.popleft()
@@ -941,7 +943,7 @@ def _recombine_set_tokens(tokens: list[str]) -> list[str]:
941
943
 
942
944
 
943
945
  def _tokenize_type_spec(spec: str) -> list[str]:
944
- def postprocess(item):
946
+ def postprocess(item: str) -> list[str]:
945
947
  if _default_regex.match(item):
946
948
  default = item[:7]
947
949
  # can't be separated by anything other than a single space
@@ -962,7 +964,7 @@ def _tokenize_type_spec(spec: str) -> list[str]:
962
964
 
963
965
 
964
966
  def _token_type(token: str, location: str | None = None) -> str:
965
- def is_numeric(token):
967
+ def is_numeric(token: str) -> bool:
966
968
  try:
967
969
  # use complex to make sure every numeric value is detected as literal
968
970
  complex(token)
@@ -1026,7 +1028,7 @@ def _convert_numpy_type_spec(
1026
1028
  if translations is None:
1027
1029
  translations = {}
1028
1030
 
1029
- def convert_obj(obj, translations, default_translation):
1031
+ def convert_obj(obj: str, translations: dict[str, str], default_translation: str) -> str:
1030
1032
  translation = translations.get(obj, obj)
1031
1033
 
1032
1034
  # use :class: (the default) only if obj is not a standard singleton
@@ -1155,6 +1157,7 @@ class NumpyDocstring(GoogleDocstring):
1155
1157
  The lines of the docstring in a list.
1156
1158
 
1157
1159
  """
1160
+
1158
1161
  def __init__(
1159
1162
  self,
1160
1163
  docstring: str | list[str],
@@ -1180,13 +1183,13 @@ class NumpyDocstring(GoogleDocstring):
1180
1183
  elif filepath is None:
1181
1184
  filepath = ""
1182
1185
 
1183
- return ":".join([filepath, "docstring of %s" % name])
1186
+ return f"{filepath}:docstring of {name}"
1184
1187
 
1185
1188
  def _escape_args_and_kwargs(self, name: str) -> str:
1186
1189
  func = super()._escape_args_and_kwargs
1187
1190
 
1188
1191
  if ", " in name:
1189
- return ", ".join(func(param) for param in name.split(", "))
1192
+ return ", ".join(map(func, name.split(", ")))
1190
1193
  else:
1191
1194
  return func(name)
1192
1195
 
@@ -1233,7 +1236,7 @@ class NumpyDocstring(GoogleDocstring):
1233
1236
  line1, line2 = self._lines.get(0), self._lines.get(1)
1234
1237
  return (not self._lines or
1235
1238
  self._is_section_header() or
1236
- ['', ''] == [line1, line2] or
1239
+ (line1 == line2 == '') or
1237
1240
  (self._is_in_section and
1238
1241
  line1 and
1239
1242
  not self._is_indented(line1, self._section_indent)))
@@ -1269,7 +1272,7 @@ class NumpyDocstring(GoogleDocstring):
1269
1272
  func_name1, func_name2, :meth:`func_name`, func_name3
1270
1273
 
1271
1274
  """
1272
- items = []
1275
+ items: list[tuple[str, list[str], str | None]] = []
1273
1276
 
1274
1277
  def parse_item_name(text: str) -> tuple[str, str | None]:
1275
1278
  """Match ':role:`name`' or 'name'"""
@@ -1286,10 +1289,12 @@ class NumpyDocstring(GoogleDocstring):
1286
1289
  if not name:
1287
1290
  return
1288
1291
  name, role = parse_item_name(name)
1289
- items.append((name, list(rest), role))
1290
- del rest[:]
1292
+ items.append((name, rest.copy(), role))
1293
+ rest.clear()
1291
1294
 
1292
- def translate(func, description, role):
1295
+ def translate(
1296
+ func: str, description: list[str], role: str | None,
1297
+ ) -> tuple[str, list[str], str | None]:
1293
1298
  translations = self._config.napoleon_type_aliases
1294
1299
  if role is not None or not translations:
1295
1300
  return func, description, role
@@ -1336,10 +1341,7 @@ class NumpyDocstring(GoogleDocstring):
1336
1341
  return []
1337
1342
 
1338
1343
  # apply type aliases
1339
- items = [
1340
- translate(func, description, role)
1341
- for func, description, role in items
1342
- ]
1344
+ items = list(starmap(translate, items))
1343
1345
 
1344
1346
  lines: list[str] = []
1345
1347
  last_had_desc = True
sphinx/ext/todo.py CHANGED
@@ -7,7 +7,9 @@ with a backlink to the original location.
7
7
 
8
8
  from __future__ import annotations
9
9
 
10
- from typing import TYPE_CHECKING, Any, cast
10
+ import functools
11
+ import operator
12
+ from typing import TYPE_CHECKING, Any, ClassVar, cast
11
13
 
12
14
  from docutils import nodes
13
15
  from docutils.parsers.rst import directives
@@ -26,7 +28,7 @@ if TYPE_CHECKING:
26
28
 
27
29
  from sphinx.application import Sphinx
28
30
  from sphinx.environment import BuildEnvironment
29
- from sphinx.util.typing import OptionSpec
31
+ from sphinx.util.typing import ExtensionMetadata, OptionSpec
30
32
  from sphinx.writers.html import HTML5Translator
31
33
  from sphinx.writers.latex import LaTeXTranslator
32
34
 
@@ -51,7 +53,7 @@ class Todo(BaseAdmonition, SphinxDirective):
51
53
  required_arguments = 0
52
54
  optional_arguments = 0
53
55
  final_argument_whitespace = False
54
- option_spec: OptionSpec = {
56
+ option_spec: ClassVar[OptionSpec] = {
55
57
  'class': directives.class_option,
56
58
  'name': directives.unchanged,
57
59
  }
@@ -85,7 +87,7 @@ class TodoDomain(Domain):
85
87
  def clear_doc(self, docname: str) -> None:
86
88
  self.todos.pop(docname, None)
87
89
 
88
- def merge_domaindata(self, docnames: list[str], otherdata: dict) -> None:
90
+ def merge_domaindata(self, docnames: list[str], otherdata: dict[str, Any]) -> None:
89
91
  for docname in docnames:
90
92
  self.todos[docname] = otherdata['todos'][docname]
91
93
 
@@ -110,7 +112,7 @@ class TodoList(SphinxDirective):
110
112
  required_arguments = 0
111
113
  optional_arguments = 0
112
114
  final_argument_whitespace = False
113
- option_spec: OptionSpec = {}
115
+ option_spec: ClassVar[OptionSpec] = {}
114
116
 
115
117
  def run(self) -> list[Node]:
116
118
  # Simply insert an empty todolist node which will be replaced later
@@ -129,7 +131,8 @@ class TodoListProcessor:
129
131
  self.process(doctree, docname)
130
132
 
131
133
  def process(self, doctree: nodes.document, docname: str) -> None:
132
- todos: list[todo_node] = sum(self.domain.todos.values(), [])
134
+ todos: list[todo_node] = functools.reduce(
135
+ operator.iadd, self.domain.todos.values(), [])
133
136
  for node in list(doctree.findall(todolist)):
134
137
  if not self.config.todo_include_todos:
135
138
  node.parent.remove(node)
@@ -221,7 +224,7 @@ def latex_depart_todo_node(self: LaTeXTranslator, node: todo_node) -> None:
221
224
  self.body.append('\\end{sphinxadmonition}\n')
222
225
 
223
226
 
224
- def setup(app: Sphinx) -> dict[str, Any]:
227
+ def setup(app: Sphinx) -> ExtensionMetadata:
225
228
  app.add_event('todo-defined')
226
229
  app.add_config_value('todo_include_todos', False, 'html')
227
230
  app.add_config_value('todo_link_only', False, 'html')
sphinx/ext/viewcode.py CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import operator
5
6
  import posixpath
6
7
  import traceback
7
8
  from importlib import import_module
@@ -22,11 +23,12 @@ from sphinx.util.display import status_iterator
22
23
  from sphinx.util.nodes import make_refnode
23
24
 
24
25
  if TYPE_CHECKING:
25
- from collections.abc import Generator, Iterable
26
+ from collections.abc import Iterable, Iterator
26
27
 
27
28
  from sphinx.application import Sphinx
28
29
  from sphinx.builders import Builder
29
30
  from sphinx.environment import BuildEnvironment
31
+ from sphinx.util.typing import ExtensionMetadata
30
32
 
31
33
  logger = logging.getLogger(__name__)
32
34
 
@@ -79,9 +81,7 @@ def is_supported_builder(builder: Builder) -> bool:
79
81
  return False
80
82
  if builder.name == 'singlehtml':
81
83
  return False
82
- if builder.name.startswith('epub') and not builder.config.viewcode_enable_epub:
83
- return False
84
- return True
84
+ return not (builder.name.startswith('epub') and not builder.config.viewcode_enable_epub)
85
85
 
86
86
 
87
87
  def doctree_read(app: Sphinx, doctree: Node) -> None:
@@ -185,6 +185,7 @@ def env_purge_doc(app: Sphinx, env: BuildEnvironment, docname: str) -> None:
185
185
 
186
186
  class ViewcodeAnchorTransform(SphinxPostTransform):
187
187
  """Convert or remove viewcode_anchor nodes depends on builder."""
188
+
188
189
  default_priority = 100
189
190
 
190
191
  def run(self, **kwargs: Any) -> None:
@@ -239,7 +240,7 @@ def should_generate_module_page(app: Sphinx, modname: str) -> bool:
239
240
  return True
240
241
 
241
242
 
242
- def collect_pages(app: Sphinx) -> Generator[tuple[str, dict[str, Any], str], None, None]:
243
+ def collect_pages(app: Sphinx) -> Iterator[tuple[str, dict[str, Any], str]]:
243
244
  env = app.builder.env
244
245
  if not hasattr(env, '_viewcode_modules'):
245
246
  return
@@ -254,7 +255,7 @@ def collect_pages(app: Sphinx) -> Generator[tuple[str, dict[str, Any], str], Non
254
255
  sorted(env._viewcode_modules.items()),
255
256
  __('highlighting module code... '), "blue",
256
257
  len(env._viewcode_modules),
257
- app.verbosity, lambda x: x[0]):
258
+ app.verbosity, operator.itemgetter(0)):
258
259
  if not entry:
259
260
  continue
260
261
  if not should_generate_module_page(app, modname):
@@ -340,11 +341,11 @@ def collect_pages(app: Sphinx) -> Generator[tuple[str, dict[str, Any], str], Non
340
341
  yield (posixpath.join(OUTPUT_DIRNAME, 'index'), context, 'page.html')
341
342
 
342
343
 
343
- def setup(app: Sphinx) -> dict[str, Any]:
344
- app.add_config_value('viewcode_import', None, False)
345
- app.add_config_value('viewcode_enable_epub', False, False)
346
- app.add_config_value('viewcode_follow_imported_members', True, False)
347
- app.add_config_value('viewcode_line_numbers', False, 'env', (bool,))
344
+ def setup(app: Sphinx) -> ExtensionMetadata:
345
+ app.add_config_value('viewcode_import', None, '')
346
+ app.add_config_value('viewcode_enable_epub', False, '')
347
+ app.add_config_value('viewcode_follow_imported_members', True, '')
348
+ app.add_config_value('viewcode_line_numbers', False, 'env', bool)
348
349
  app.connect('doctree-read', doctree_read)
349
350
  app.connect('env-merge-info', env_merge_info)
350
351
  app.connect('env-purge-doc', env_purge_doc)
sphinx/extension.py CHANGED
@@ -13,6 +13,7 @@ from sphinx.util import logging
13
13
  if TYPE_CHECKING:
14
14
  from sphinx.application import Sphinx
15
15
  from sphinx.config import Config
16
+ from sphinx.util.typing import ExtensionMetadata
16
17
 
17
18
  logger = logging.getLogger(__name__)
18
19
 
@@ -21,7 +22,7 @@ class Extension:
21
22
  def __init__(self, name: str, module: Any, **kwargs: Any) -> None:
22
23
  self.name = name
23
24
  self.module = module
24
- self.metadata = kwargs
25
+ self.metadata: ExtensionMetadata = kwargs # type: ignore[assignment]
25
26
  self.version = kwargs.pop('version', 'unknown version')
26
27
 
27
28
  # The extension supports parallel read or not. The default value
@@ -50,8 +51,13 @@ def verify_needs_extensions(app: Sphinx, config: Config) -> None:
50
51
  for extname, reqversion in config.needs_extensions.items():
51
52
  extension = app.extensions.get(extname)
52
53
  if extension is None:
53
- logger.warning(__('The %s extension is required by needs_extensions settings, '
54
- 'but it is not loaded.'), extname)
54
+ logger.warning(
55
+ __(
56
+ 'The %s extension is required by needs_extensions settings, '
57
+ 'but it is not loaded.'
58
+ ),
59
+ extname,
60
+ )
55
61
  continue
56
62
 
57
63
  fulfilled = True
@@ -66,13 +72,17 @@ def verify_needs_extensions(app: Sphinx, config: Config) -> None:
66
72
  fulfilled = False
67
73
 
68
74
  if not fulfilled:
69
- raise VersionRequirementError(__('This project needs the extension %s at least in '
70
- 'version %s and therefore cannot be built with '
71
- 'the loaded version (%s).') %
72
- (extname, reqversion, extension.version))
75
+ raise VersionRequirementError(
76
+ __(
77
+ 'This project needs the extension %s at least in '
78
+ 'version %s and therefore cannot be built with '
79
+ 'the loaded version (%s).'
80
+ )
81
+ % (extname, reqversion, extension.version)
82
+ )
73
83
 
74
84
 
75
- def setup(app: Sphinx) -> dict[str, Any]:
85
+ def setup(app: Sphinx) -> ExtensionMetadata:
76
86
  app.connect('config-inited', verify_needs_extensions, priority=800)
77
87
 
78
88
  return {
sphinx/highlighting.py CHANGED
@@ -42,9 +42,7 @@ lexer_classes: dict[str, type[Lexer] | partial[Lexer]] = {
42
42
  }
43
43
 
44
44
 
45
- escape_hl_chars = {ord('\\'): '\\PYGZbs{}',
46
- ord('{'): '\\PYGZob{}',
47
- ord('}'): '\\PYGZcb{}'}
45
+ escape_hl_chars = {ord('\\'): '\\PYGZbs{}', ord('{'): '\\PYGZob{}', ord('}'): '\\PYGZcb{}'}
48
46
 
49
47
  # used if Pygments is available
50
48
  # MEMO: no use of \protected here to avoid having to do hyperref extras,
@@ -57,7 +55,7 @@ escape_hl_chars = {ord('\\'): '\\PYGZbs{}',
57
55
  # MEMO: the Pygments escapes with \char`\<char> syntax, if the document
58
56
  # uses old OT1 font encoding, work correctly only in monospace font.
59
57
  # MEMO: the Pygmentize output mark-up is always with a {} after.
60
- _LATEX_ADD_STYLES = r'''
58
+ _LATEX_ADD_STYLES = r"""
61
59
  % Sphinx redefinitions
62
60
  % Originally to obtain a straight single quote via package textcomp, then
63
61
  % to fix problems for the 5.0.0 inline code highlighting (captions!).
@@ -82,7 +80,7 @@ _LATEX_ADD_STYLES = r'''
82
80
  % use \protected to allow syntax highlighting in captions
83
81
  \protected\def\PYG#1#2{\PYG@reset\PYG@toks#1+\relax+{\PYG@do{#2}}}
84
82
  \makeatother
85
- '''
83
+ """
86
84
 
87
85
 
88
86
  class PygmentsBridge:
@@ -91,8 +89,9 @@ class PygmentsBridge:
91
89
  html_formatter = HtmlFormatter
92
90
  latex_formatter = LatexFormatter
93
91
 
94
- def __init__(self, dest: str = 'html', stylename: str = 'sphinx',
95
- latex_engine: str | None = None) -> None:
92
+ def __init__(
93
+ self, dest: str = 'html', stylename: str = 'sphinx', latex_engine: str | None = None
94
+ ) -> None:
96
95
  self.dest = dest
97
96
  self.latex_engine = latex_engine
98
97
 
@@ -104,8 +103,8 @@ class PygmentsBridge:
104
103
  self.formatter = self.latex_formatter
105
104
  self.formatter_args['commandprefix'] = 'PYG'
106
105
 
107
- def get_style(self, stylename: str) -> Style:
108
- if stylename is None or stylename == 'sphinx':
106
+ def get_style(self, stylename: str) -> type[Style]:
107
+ if not stylename or stylename == 'sphinx':
109
108
  return SphinxStyle
110
109
  elif stylename == 'none':
111
110
  return NoneStyle
@@ -119,8 +118,14 @@ class PygmentsBridge:
119
118
  kwargs.update(self.formatter_args)
120
119
  return self.formatter(**kwargs)
121
120
 
122
- def get_lexer(self, source: str, lang: str, opts: dict | None = None,
123
- force: bool = False, location: Any = None) -> Lexer:
121
+ def get_lexer(
122
+ self,
123
+ source: str,
124
+ lang: str,
125
+ opts: dict | None = None,
126
+ force: bool = False,
127
+ location: Any = None,
128
+ ) -> Lexer:
124
129
  if not opts:
125
130
  opts = {}
126
131
 
@@ -146,8 +151,9 @@ class PygmentsBridge:
146
151
  else:
147
152
  lexer = get_lexer_by_name(lang, **opts)
148
153
  except ClassNotFound:
149
- logger.warning(__('Pygments lexer name %r is not known'), lang,
150
- location=location)
154
+ logger.warning(
155
+ __('Pygments lexer name %r is not known'), lang, location=location
156
+ )
151
157
  lexer = lexer_classes['none'](**opts)
152
158
 
153
159
  if not force:
@@ -155,8 +161,15 @@ class PygmentsBridge:
155
161
 
156
162
  return lexer
157
163
 
158
- def highlight_block(self, source: str, lang: str, opts: dict | None = None,
159
- force: bool = False, location: Any = None, **kwargs: Any) -> str:
164
+ def highlight_block(
165
+ self,
166
+ source: str,
167
+ lang: str,
168
+ opts: dict | None = None,
169
+ force: bool = False,
170
+ location: Any = None,
171
+ **kwargs: Any,
172
+ ) -> str:
160
173
  if not isinstance(source, str):
161
174
  source = source.decode()
162
175
 
@@ -173,11 +186,17 @@ class PygmentsBridge:
173
186
  lang = 'none' # automatic highlighting failed.
174
187
  else:
175
188
  logger.warning(
176
- __('Lexing literal_block %r as "%s" resulted in an error at token: %r. '
177
- 'Retrying in relaxed mode.'),
178
- source, lang, str(err),
179
- type='misc', subtype='highlighting_failure',
180
- location=location)
189
+ __(
190
+ 'Lexing literal_block %r as "%s" resulted in an error at token: %r. '
191
+ 'Retrying in relaxed mode.'
192
+ ),
193
+ source,
194
+ lang,
195
+ str(err),
196
+ type='misc',
197
+ subtype='highlighting_failure',
198
+ location=location,
199
+ )
181
200
  if force:
182
201
  lang = 'none'
183
202
  else:
sphinx/io.py CHANGED
@@ -1,4 +1,5 @@
1
1
  """Input/Output files"""
2
+
2
3
  from __future__ import annotations
3
4
 
4
5
  from typing import TYPE_CHECKING, Any
@@ -46,6 +47,7 @@ class SphinxBaseReader(standalone.Reader):
46
47
 
47
48
  def __init__(self, *args: Any, **kwargs: Any) -> None:
48
49
  from sphinx.application import Sphinx
50
+
49
51
  if len(args) > 0 and isinstance(args[0], Sphinx):
50
52
  self._app = args[0]
51
53
  self._env = self._app.env
@@ -54,7 +56,7 @@ class SphinxBaseReader(standalone.Reader):
54
56
  super().__init__(*args, **kwargs)
55
57
 
56
58
  def setup(self, app: Sphinx) -> None:
57
- self._app = app # hold application object only for compatibility
59
+ self._app = app # hold application object only for compatibility
58
60
  self._env = app.env
59
61
 
60
62
  def get_transforms(self) -> list[type[Transform]]:
@@ -96,9 +98,9 @@ class SphinxStandaloneReader(SphinxBaseReader):
96
98
  self.transforms = self.transforms + app.registry.get_transforms()
97
99
  super().setup(app)
98
100
 
99
- def read(self, source: Input, parser: Parser, settings: Values) -> nodes.document:
101
+ def read(self, source: Input, parser: Parser, settings: Values) -> nodes.document: # type: ignore[type-arg]
100
102
  self.source = source
101
- if not self.parser:
103
+ if not self.parser: # type: ignore[has-type]
102
104
  self.parser = parser
103
105
  self.settings = settings
104
106
  self.input = self.read_source(settings.env)
@@ -128,9 +130,15 @@ class SphinxI18nReader(SphinxBaseReader):
128
130
  super().setup(app)
129
131
 
130
132
  self.transforms = self.transforms + app.registry.get_transforms()
131
- unused = [PreserveTranslatableMessages, Locale, RemoveTranslatableInline,
132
- AutoIndexUpgrader, SphinxDomains, DoctreeReadEvent,
133
- UIDTransform]
133
+ unused = [
134
+ PreserveTranslatableMessages,
135
+ Locale,
136
+ RemoveTranslatableInline,
137
+ AutoIndexUpgrader,
138
+ SphinxDomains,
139
+ DoctreeReadEvent,
140
+ UIDTransform,
141
+ ]
134
142
  for transform in unused:
135
143
  if transform in self.transforms:
136
144
  self.transforms.remove(transform)
@@ -152,6 +160,7 @@ def SphinxDummySourceClass(source: Any, *args: Any, **kwargs: Any) -> Any:
152
160
 
153
161
  class SphinxFileInput(FileInput):
154
162
  """A basic FileInput for Sphinx."""
163
+
155
164
  def __init__(self, *args: Any, **kwargs: Any) -> None:
156
165
  kwargs['error_handler'] = 'sphinx'
157
166
  super().__init__(*args, **kwargs)
@@ -170,7 +179,7 @@ def create_publisher(app: Sphinx, filetype: str) -> Publisher:
170
179
  # CommonMarkParser.
171
180
  from docutils.parsers.rst import Parser as RSTParser
172
181
 
173
- parser.settings_spec = RSTParser.settings_spec
182
+ parser.settings_spec = RSTParser.settings_spec # type: ignore[misc]
174
183
 
175
184
  pub = Publisher(
176
185
  reader=reader,
@@ -180,7 +189,7 @@ def create_publisher(app: Sphinx, filetype: str) -> Publisher:
180
189
  destination=NullOutput(),
181
190
  )
182
191
  # Propagate exceptions by default when used programmatically:
183
- defaults = {"traceback": True, **app.env.settings}
192
+ defaults = {'traceback': True, **app.env.settings}
184
193
  # Set default settings
185
194
  if docutils.__version_info__[:2] >= (0, 19):
186
195
  pub.get_settings(**defaults)