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
@@ -37,7 +37,7 @@ import re
37
37
  from collections.abc import Iterable, Sequence
38
38
  from importlib import import_module
39
39
  from os import path
40
- from typing import TYPE_CHECKING, Any, cast
40
+ from typing import TYPE_CHECKING, Any, ClassVar, cast
41
41
 
42
42
  from docutils import nodes
43
43
  from docutils.parsers.rst import directives
@@ -58,7 +58,7 @@ if TYPE_CHECKING:
58
58
 
59
59
  from sphinx.application import Sphinx
60
60
  from sphinx.environment import BuildEnvironment
61
- from sphinx.util.typing import OptionSpec
61
+ from sphinx.util.typing import ExtensionMetadata, OptionSpec
62
62
  from sphinx.writers.html import HTML5Translator
63
63
  from sphinx.writers.latex import LaTeXTranslator
64
64
  from sphinx.writers.texinfo import TexinfoTranslator
@@ -123,11 +123,8 @@ def import_classes(name: str, currmodule: str) -> Any:
123
123
  return [target]
124
124
  elif inspect.ismodule(target):
125
125
  # If imported object is a module, return classes defined on it
126
- classes = []
127
- for cls in target.__dict__.values():
128
- if inspect.isclass(cls) and cls.__module__ == target.__name__:
129
- classes.append(cls)
130
- return classes
126
+ return [cls for cls in target.__dict__.values()
127
+ if inspect.isclass(cls) and cls.__module__ == target.__name__]
131
128
  raise InheritanceException('%r specified for inheritance diagram is '
132
129
  'not a class or module' % name)
133
130
 
@@ -142,6 +139,7 @@ class InheritanceGraph:
142
139
  from all the way to the root "object", and then is able to generate a
143
140
  graphviz dot graph from them.
144
141
  """
142
+
145
143
  def __init__(self, class_names: list[str], currmodule: str, show_builtins: bool = False,
146
144
  private_bases: bool = False, parts: int = 0,
147
145
  aliases: dict[str, str] | None = None, top_classes: Sequence[Any] = (),
@@ -272,10 +270,10 @@ class InheritanceGraph:
272
270
  }
273
271
 
274
272
  def _format_node_attrs(self, attrs: dict[str, Any]) -> str:
275
- return ','.join(['%s=%s' % x for x in sorted(attrs.items())])
273
+ return ','.join(f'{k}={v}' for k, v in sorted(attrs.items()))
276
274
 
277
275
  def _format_graph_attrs(self, attrs: dict[str, Any]) -> str:
278
- return ''.join(['%s=%s;\n' % x for x in sorted(attrs.items())])
276
+ return ''.join(f'{k}={v};\n' for k, v in sorted(attrs.items()))
279
277
 
280
278
  def generate_dot(self, name: str, urls: dict[str, str] | None = None,
281
279
  env: BuildEnvironment | None = None,
@@ -309,34 +307,35 @@ class InheritanceGraph:
309
307
  n_attrs.update(env.config.inheritance_node_attrs)
310
308
  e_attrs.update(env.config.inheritance_edge_attrs)
311
309
 
312
- res: list[str] = []
313
- res.append('digraph %s {\n' % name)
314
- res.append(self._format_graph_attrs(g_attrs))
310
+ res: list[str] = [
311
+ f'digraph {name} {{\n',
312
+ self._format_graph_attrs(g_attrs),
313
+ ]
315
314
 
316
315
  for name, fullname, bases, tooltip in sorted(self.class_info):
317
316
  # Write the node
318
317
  this_node_attrs = n_attrs.copy()
319
318
  if fullname in urls:
320
- this_node_attrs['URL'] = '"%s"' % urls[fullname]
321
- this_node_attrs['target'] = '"_top"'
319
+ this_node_attrs["URL"] = '"%s"' % urls[fullname]
320
+ this_node_attrs["target"] = '"_top"'
322
321
  if tooltip:
323
- this_node_attrs['tooltip'] = tooltip
324
- res.append(' "%s" [%s];\n' %
325
- (name, self._format_node_attrs(this_node_attrs)))
322
+ this_node_attrs["tooltip"] = tooltip
323
+ res.append(' "%s" [%s];\n' % (name, self._format_node_attrs(this_node_attrs)))
326
324
 
327
325
  # Write the edges
328
- for base_name in bases:
329
- res.append(' "%s" -> "%s" [%s];\n' %
330
- (base_name, name,
331
- self._format_node_attrs(e_attrs)))
332
- res.append('}\n')
333
- return ''.join(res)
326
+ res.extend(
327
+ ' "%s" -> "%s" [%s];\n' % (base_name, name, self._format_node_attrs(e_attrs))
328
+ for base_name in bases
329
+ )
330
+ res.append("}\n")
331
+ return "".join(res)
334
332
 
335
333
 
336
334
  class inheritance_diagram(graphviz):
337
335
  """
338
336
  A docutils node to use as a placeholder for the inheritance diagram.
339
337
  """
338
+
340
339
  pass
341
340
 
342
341
 
@@ -344,11 +343,12 @@ class InheritanceDiagram(SphinxDirective):
344
343
  """
345
344
  Run when the inheritance_diagram directive is first encountered.
346
345
  """
346
+
347
347
  has_content = False
348
348
  required_arguments = 1
349
349
  optional_arguments = 0
350
350
  final_argument_whitespace = True
351
- option_spec: OptionSpec = {
351
+ option_spec: ClassVar[OptionSpec] = {
352
352
  'parts': int,
353
353
  'private-bases': directives.flag,
354
354
  'caption': directives.unchanged,
@@ -378,7 +378,7 @@ class InheritanceDiagram(SphinxDirective):
378
378
  aliases=self.config.inheritance_alias,
379
379
  top_classes=node['top-classes'])
380
380
  except InheritanceException as err:
381
- return [node.document.reporter.warning(err, line=self.lineno)]
381
+ return [node.document.reporter.warning(err, line=self.lineno)] # type: ignore[union-attr]
382
382
 
383
383
  # Create xref nodes for each target of the graph's image map and
384
384
  # add them to the doc tree so that Sphinx can resolve the
@@ -386,7 +386,7 @@ class InheritanceDiagram(SphinxDirective):
386
386
  # removed from the doctree after we're done with them.
387
387
  for name in graph.get_all_class_names():
388
388
  refnodes, x = class_role( # type: ignore[call-arg,misc]
389
- 'class', ':class:`%s`' % name, name, 0, self.state) # type: ignore[arg-type]
389
+ 'class', ':class:`%s`' % name, name, 0, self.state)
390
390
  node.extend(refnodes)
391
391
  # Store the graph object so we can use it to generate the
392
392
  # dot file later
@@ -477,7 +477,7 @@ def skip(self: nodes.NodeVisitor, node: inheritance_diagram) -> None:
477
477
  raise nodes.SkipNode
478
478
 
479
479
 
480
- def setup(app: Sphinx) -> dict[str, Any]:
480
+ def setup(app: Sphinx) -> ExtensionMetadata:
481
481
  app.setup_extension('sphinx.ext.graphviz')
482
482
  app.add_node(
483
483
  inheritance_diagram,
@@ -487,8 +487,8 @@ def setup(app: Sphinx) -> dict[str, Any]:
487
487
  man=(skip, None),
488
488
  texinfo=(texinfo_visit_inheritance_diagram, None))
489
489
  app.add_directive('inheritance-diagram', InheritanceDiagram)
490
- app.add_config_value('inheritance_graph_attrs', {}, False)
491
- app.add_config_value('inheritance_node_attrs', {}, False)
492
- app.add_config_value('inheritance_edge_attrs', {}, False)
493
- app.add_config_value('inheritance_alias', {}, False)
490
+ app.add_config_value('inheritance_graph_attrs', {}, '')
491
+ app.add_config_value('inheritance_node_attrs', {}, '')
492
+ app.add_config_value('inheritance_edge_attrs', {}, '')
493
+ app.add_config_value('inheritance_alias', {}, '')
494
494
  return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
sphinx/ext/intersphinx.py CHANGED
@@ -34,6 +34,7 @@ from docutils.utils import relative_path
34
34
  import sphinx
35
35
  from sphinx.addnodes import pending_xref
36
36
  from sphinx.builders.html import INVENTORY_FILENAME
37
+ from sphinx.deprecation import _deprecation_warning
37
38
  from sphinx.errors import ExtensionError
38
39
  from sphinx.locale import _, __
39
40
  from sphinx.transforms.post_transforms import ReferencesResolver
@@ -53,7 +54,7 @@ if TYPE_CHECKING:
53
54
  from sphinx.config import Config
54
55
  from sphinx.domains import Domain
55
56
  from sphinx.environment import BuildEnvironment
56
- from sphinx.util.typing import Inventory, InventoryItem, RoleFunction
57
+ from sphinx.util.typing import ExtensionMetadata, Inventory, InventoryItem, RoleFunction
57
58
 
58
59
  InventoryCacheEntry = tuple[Union[str, None], int, Inventory]
59
60
 
@@ -245,7 +246,7 @@ def fetch_inventory_group(
245
246
  for fail in failures:
246
247
  logger.info(*fail)
247
248
  else:
248
- issues = '\n'.join([f[0] % f[1:] for f in failures])
249
+ issues = '\n'.join(f[0] % f[1:] for f in failures)
249
250
  logger.warning(__("failed to reach any of the inventories "
250
251
  "with the following issues:") + "\n" + issues)
251
252
 
@@ -334,8 +335,10 @@ def _resolve_reference_in_domain_by_target(
334
335
  if target in inventory[objtype]:
335
336
  # Case sensitive match, use it
336
337
  data = inventory[objtype][target]
337
- elif objtype == 'std:term':
338
- # Check for potential case insensitive matches for terms only
338
+ elif objtype in {'std:label', 'std:term'}:
339
+ # Some types require case insensitive matches:
340
+ # * 'term': https://github.com/sphinx-doc/sphinx/issues/9291
341
+ # * 'label': https://github.com/sphinx-doc/sphinx/issues/12008
339
342
  target_lower = target.lower()
340
343
  insensitive_matches = list(filter(lambda k: k.lower() == target_lower,
341
344
  inventory[objtype].keys()))
@@ -479,7 +482,6 @@ def resolve_reference_detect_inventory(env: BuildEnvironment,
479
482
  to form ``inv_name:newtarget``. If ``inv_name`` is a named inventory, then resolution
480
483
  is tried in that inventory with the new target.
481
484
  """
482
-
483
485
  # ordinary direct lookup, use data as is
484
486
  res = resolve_reference_any_inventory(env, True, node, contnode)
485
487
  if res is not None:
@@ -501,7 +503,6 @@ def resolve_reference_detect_inventory(env: BuildEnvironment,
501
503
  def missing_reference(app: Sphinx, env: BuildEnvironment, node: pending_xref,
502
504
  contnode: TextElement) -> nodes.reference | None:
503
505
  """Attempt to resolve a missing reference via intersphinx references."""
504
-
505
506
  return resolve_reference_detect_inventory(env, node, contnode)
506
507
 
507
508
 
@@ -533,17 +534,90 @@ class IntersphinxRole(SphinxRole):
533
534
  assert self.name == self.orig_name.lower()
534
535
  inventory, name_suffix = self.get_inventory_and_name_suffix(self.orig_name)
535
536
  if inventory and not inventory_exists(self.env, inventory):
536
- logger.warning(__('inventory for external cross-reference not found: %s'),
537
- inventory, location=(self.env.docname, self.lineno))
537
+ self._emit_warning(
538
+ __('inventory for external cross-reference not found: %r'), inventory
539
+ )
538
540
  return [], []
539
541
 
540
- role_name = self.get_role_name(name_suffix)
542
+ domain_name, role_name = self._get_domain_role(name_suffix)
543
+
541
544
  if role_name is None:
542
- logger.warning(__('role for external cross-reference not found: %s'), name_suffix,
543
- location=(self.env.docname, self.lineno))
545
+ self._emit_warning(
546
+ __('invalid external cross-reference suffix: %r'), name_suffix
547
+ )
544
548
  return [], []
545
549
 
546
- result, messages = self.invoke_role(role_name)
550
+ # attempt to find a matching role function
551
+ role_func: RoleFunction | None
552
+
553
+ if domain_name is not None:
554
+ # the user specified a domain, so we only check that
555
+ if (domain := self.env.domains.get(domain_name)) is None:
556
+ self._emit_warning(
557
+ __('domain for external cross-reference not found: %r'), domain_name
558
+ )
559
+ return [], []
560
+ if (role_func := domain.roles.get(role_name)) is None:
561
+ msg = 'role for external cross-reference not found in domain %r: %r'
562
+ if (
563
+ object_types := domain.object_types.get(role_name)
564
+ ) is not None and object_types.roles:
565
+ self._emit_warning(
566
+ __(f'{msg} (perhaps you meant one of: %s)'),
567
+ domain_name,
568
+ role_name,
569
+ self._concat_strings(object_types.roles),
570
+ )
571
+ else:
572
+ self._emit_warning(__(msg), domain_name, role_name)
573
+ return [], []
574
+
575
+ else:
576
+ # the user did not specify a domain,
577
+ # so we check first the default (if available) then standard domains
578
+ domains: list[Domain] = []
579
+ if default_domain := self.env.temp_data.get('default_domain'):
580
+ domains.append(default_domain)
581
+ if (
582
+ std_domain := self.env.domains.get('std')
583
+ ) is not None and std_domain not in domains:
584
+ domains.append(std_domain)
585
+
586
+ role_func = None
587
+ for domain in domains:
588
+ if (role_func := domain.roles.get(role_name)) is not None:
589
+ domain_name = domain.name
590
+ break
591
+
592
+ if role_func is None or domain_name is None:
593
+ domains_str = self._concat_strings(d.name for d in domains)
594
+ msg = 'role for external cross-reference not found in domains %s: %r'
595
+ possible_roles: set[str] = set()
596
+ for d in domains:
597
+ if o := d.object_types.get(role_name):
598
+ possible_roles.update(f'{d.name}:{r}' for r in o.roles)
599
+ if possible_roles:
600
+ msg = f'{msg} (perhaps you meant one of: %s)'
601
+ self._emit_warning(
602
+ __(msg),
603
+ domains_str,
604
+ role_name,
605
+ self._concat_strings(possible_roles),
606
+ )
607
+ else:
608
+ self._emit_warning(__(msg), domains_str, role_name)
609
+ return [], []
610
+
611
+ result, messages = role_func(
612
+ f'{domain_name}:{role_name}',
613
+ self.rawtext,
614
+ self.text,
615
+ self.lineno,
616
+ self.inliner,
617
+ self.options,
618
+ self.content,
619
+ )
620
+
547
621
  for node in result:
548
622
  if isinstance(node, pending_xref):
549
623
  node['intersphinx'] = True
@@ -552,13 +626,17 @@ class IntersphinxRole(SphinxRole):
552
626
  return result, messages
553
627
 
554
628
  def get_inventory_and_name_suffix(self, name: str) -> tuple[str | None, str]:
629
+ """Extract an inventory name (if any) and ``domain+name`` suffix from a role *name*.
630
+ and the domain+name suffix.
631
+
632
+ The role name is expected to be of one of the following forms:
633
+
634
+ - ``external+inv:name`` -- explicit inventory and name, any domain.
635
+ - ``external+inv:domain:name`` -- explicit inventory, domain and name.
636
+ - ``external:name`` -- any inventory and domain, explicit name.
637
+ - ``external:domain:name`` -- any inventory, explicit domain and name.
638
+ """
555
639
  assert name.startswith('external'), name
556
- # either we have an explicit inventory name, i.e,
557
- # :external+inv:role: or
558
- # :external+inv:domain:role:
559
- # or we look in all inventories, i.e.,
560
- # :external:role: or
561
- # :external:domain:role:
562
640
  suffix = name[9:]
563
641
  if name[8] == '+':
564
642
  inv_name, suffix = suffix.split(':', 1)
@@ -569,7 +647,39 @@ class IntersphinxRole(SphinxRole):
569
647
  msg = f'Malformed :external: role name: {name}'
570
648
  raise ValueError(msg)
571
649
 
650
+ def _get_domain_role(self, name: str) -> tuple[str | None, str | None]:
651
+ """Convert the *name* string into a domain and a role name.
652
+
653
+ - If *name* contains no ``:``, return ``(None, name)``.
654
+ - If *name* contains a single ``:``, the domain/role is split on this.
655
+ - If *name* contains multiple ``:``, return ``(None, None)``.
656
+ """
657
+ names = name.split(':')
658
+ if len(names) == 1:
659
+ return None, names[0]
660
+ elif len(names) == 2:
661
+ return names[0], names[1]
662
+ else:
663
+ return None, None
664
+
665
+ def _emit_warning(self, msg: str, /, *args: Any) -> None:
666
+ logger.warning(
667
+ msg,
668
+ *args,
669
+ type='intersphinx',
670
+ subtype='external',
671
+ location=(self.env.docname, self.lineno),
672
+ )
673
+
674
+ def _concat_strings(self, strings: Iterable[str]) -> str:
675
+ return ', '.join(f'{s!r}' for s in sorted(strings))
676
+
677
+ # deprecated methods
678
+
572
679
  def get_role_name(self, name: str) -> tuple[str, str] | None:
680
+ _deprecation_warning(
681
+ __name__, f'{self.__class__.__name__}.get_role_name', '', remove=(9, 0)
682
+ )
573
683
  names = name.split(':')
574
684
  if len(names) == 1:
575
685
  # role
@@ -591,6 +701,9 @@ class IntersphinxRole(SphinxRole):
591
701
  return None
592
702
 
593
703
  def is_existent_role(self, domain_name: str, role_name: str) -> bool:
704
+ _deprecation_warning(
705
+ __name__, f'{self.__class__.__name__}.is_existent_role', '', remove=(9, 0)
706
+ )
594
707
  try:
595
708
  domain = self.env.get_domain(domain_name)
596
709
  return role_name in domain.roles
@@ -598,6 +711,10 @@ class IntersphinxRole(SphinxRole):
598
711
  return False
599
712
 
600
713
  def invoke_role(self, role: tuple[str, str]) -> tuple[list[Node], list[system_message]]:
714
+ """Invoke the role described by a ``(domain, role name)`` pair."""
715
+ _deprecation_warning(
716
+ __name__, f'{self.__class__.__name__}.invoke_role', '', remove=(9, 0)
717
+ )
601
718
  domain = self.env.get_domain(role[0])
602
719
  if domain:
603
720
  role_func = domain.role(role[1])
@@ -681,11 +798,11 @@ def normalize_intersphinx_mapping(app: Sphinx, config: Config) -> None:
681
798
  config.intersphinx_mapping.pop(key)
682
799
 
683
800
 
684
- def setup(app: Sphinx) -> dict[str, Any]:
685
- app.add_config_value('intersphinx_mapping', {}, True)
686
- app.add_config_value('intersphinx_cache_limit', 5, False)
687
- app.add_config_value('intersphinx_timeout', None, False)
688
- app.add_config_value('intersphinx_disabled_reftypes', ['std:doc'], True)
801
+ def setup(app: Sphinx) -> ExtensionMetadata:
802
+ app.add_config_value('intersphinx_mapping', {}, 'env')
803
+ app.add_config_value('intersphinx_cache_limit', 5, '')
804
+ app.add_config_value('intersphinx_timeout', None, '')
805
+ app.add_config_value('intersphinx_disabled_reftypes', ['std:doc'], 'env')
689
806
  app.connect('config-inited', normalize_intersphinx_mapping, priority=800)
690
807
  app.connect('builder-inited', load_mappings)
691
808
  app.connect('source-read', install_dispatcher)
sphinx/ext/linkcode.py CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import TYPE_CHECKING, Any
5
+ from typing import TYPE_CHECKING
6
6
 
7
7
  from docutils import nodes
8
8
 
@@ -15,6 +15,7 @@ if TYPE_CHECKING:
15
15
  from docutils.nodes import Node
16
16
 
17
17
  from sphinx.application import Sphinx
18
+ from sphinx.util.typing import ExtensionMetadata
18
19
 
19
20
 
20
21
  class LinkcodeError(SphinxError):
@@ -71,7 +72,7 @@ def doctree_read(app: Sphinx, doctree: Node) -> None:
71
72
  signode += onlynode
72
73
 
73
74
 
74
- def setup(app: Sphinx) -> dict[str, Any]:
75
+ def setup(app: Sphinx) -> ExtensionMetadata:
75
76
  app.connect('doctree-read', doctree_read)
76
77
  app.add_config_value('linkcode_resolve', None, '')
77
78
  return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
sphinx/ext/mathjax.py CHANGED
@@ -21,6 +21,7 @@ from sphinx.util.math import get_node_equation_number
21
21
 
22
22
  if TYPE_CHECKING:
23
23
  from sphinx.application import Sphinx
24
+ from sphinx.util.typing import ExtensionMetadata
24
25
  from sphinx.writers.html import HTML5Translator
25
26
 
26
27
  # more information for mathjax secure url is here:
@@ -109,7 +110,7 @@ def install_mathjax(app: Sphinx, pagename: str, templatename: str, context: dict
109
110
  builder.add_js_file(app.config.mathjax_path, **options)
110
111
 
111
112
 
112
- def setup(app: Sphinx) -> dict[str, Any]:
113
+ def setup(app: Sphinx) -> ExtensionMetadata:
113
114
  app.add_html_math_renderer('mathjax',
114
115
  (html_visit_math, None),
115
116
  (html_visit_displaymath, None))
@@ -2,13 +2,17 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Any
5
+ from typing import TYPE_CHECKING, Any
6
6
 
7
7
  import sphinx
8
8
  from sphinx.application import Sphinx
9
9
  from sphinx.ext.napoleon.docstring import GoogleDocstring, NumpyDocstring
10
10
  from sphinx.util import inspect
11
11
 
12
+ if TYPE_CHECKING:
13
+ from sphinx.config import _ConfigRebuild
14
+ from sphinx.util.typing import ExtensionMetadata
15
+
12
16
 
13
17
  class Config:
14
18
  """Sphinx napoleon extension settings in `conf.py`.
@@ -261,8 +265,9 @@ class Config:
261
265
  Use the type annotations of class attributes that are documented in the docstring
262
266
  but do not have a type in the docstring.
263
267
 
264
- """
265
- _config_values = {
268
+ """ # NoQA: D301
269
+
270
+ _config_values: dict[str, tuple[Any, _ConfigRebuild]] = {
266
271
  'napoleon_google_docstring': (True, 'env'),
267
272
  'napoleon_numpy_docstring': (True, 'env'),
268
273
  'napoleon_include_init_with_doc': (False, 'env'),
@@ -288,7 +293,7 @@ class Config:
288
293
  setattr(self, name, value)
289
294
 
290
295
 
291
- def setup(app: Sphinx) -> dict[str, Any]:
296
+ def setup(app: Sphinx) -> ExtensionMetadata:
292
297
  """Sphinx extension setup function.
293
298
 
294
299
  When the extension is loaded, Sphinx imports this module and executes
@@ -326,7 +331,7 @@ def setup(app: Sphinx) -> dict[str, Any]:
326
331
 
327
332
 
328
333
  def _patch_python_domain() -> None:
329
- from sphinx.domains.python import PyObject, PyTypedField
334
+ from sphinx.domains.python._object import PyObject, PyTypedField
330
335
  from sphinx.locale import _
331
336
  for doc_field in PyObject.doc_field_types:
332
337
  if doc_field.name == 'parameter':
@@ -335,7 +340,7 @@ def _patch_python_domain() -> None:
335
340
  PyObject.doc_field_types.append(
336
341
  PyTypedField('keyword', label=_('Keyword Arguments'),
337
342
  names=('keyword', 'kwarg', 'kwparam'),
338
- typerolename='obj', typenames=('paramtype', 'kwtype'),
343
+ typerolename='class', typenames=('paramtype', 'kwtype'),
339
344
  can_collapse=True))
340
345
 
341
346
 
@@ -386,7 +391,7 @@ def _process_docstring(app: Sphinx, what: str, name: str, obj: Any,
386
391
  docstring = GoogleDocstring(result_lines, app.config, app, what, name,
387
392
  obj, options)
388
393
  result_lines = docstring.lines()
389
- lines[:] = result_lines[:]
394
+ lines[:] = result_lines.copy()
390
395
 
391
396
 
392
397
  def _skip_member(app: Sphinx, what: str, name: str, obj: Any,