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,11 +7,13 @@ for those who like elaborate docstrings.
7
7
 
8
8
  from __future__ import annotations
9
9
 
10
+ import functools
11
+ import operator
10
12
  import re
11
13
  import sys
12
14
  import warnings
13
15
  from inspect import Parameter, Signature
14
- from typing import TYPE_CHECKING, Any, Callable, TypeVar
16
+ from typing import TYPE_CHECKING, Any, Callable, ClassVar, TypeVar
15
17
 
16
18
  from docutils.statemachine import StringList
17
19
 
@@ -31,7 +33,13 @@ from sphinx.util.inspect import (
31
33
  safe_getattr,
32
34
  stringify_signature,
33
35
  )
34
- from sphinx.util.typing import OptionSpec, get_type_hints, restify, stringify_annotation
36
+ from sphinx.util.typing import (
37
+ ExtensionMetadata,
38
+ OptionSpec,
39
+ get_type_hints,
40
+ restify,
41
+ stringify_annotation,
42
+ )
35
43
 
36
44
  if TYPE_CHECKING:
37
45
  from collections.abc import Iterator, Sequence
@@ -221,7 +229,7 @@ def between(
221
229
  return
222
230
  deleted = 0
223
231
  delete = not exclude
224
- orig_lines = lines[:]
232
+ orig_lines = lines.copy()
225
233
  for i, line in enumerate(orig_lines):
226
234
  if delete:
227
235
  lines.pop(i - deleted)
@@ -243,6 +251,7 @@ def between(
243
251
  # But we define this class here to keep compatibility (see #4538)
244
252
  class Options(dict):
245
253
  """A dict/attribute hybrid that returns None on nonexisting keys."""
254
+
246
255
  def copy(self) -> Options:
247
256
  return Options(super().copy())
248
257
 
@@ -275,7 +284,7 @@ class ObjectMember:
275
284
  self.skipped = skipped
276
285
  self.class_ = class_
277
286
 
278
- def __getitem__(self, index):
287
+ def __getitem__(self, index: int) -> Any:
279
288
  warnings.warn('The tuple interface of ObjectMember is deprecated. '
280
289
  'Use (obj.__name__, obj.object) instead.',
281
290
  RemovedInSphinx80Warning, stacklevel=2)
@@ -297,6 +306,7 @@ class Documenter:
297
306
  in fact, it will be used to parse an auto directive's options that matches
298
307
  the Documenter.
299
308
  """
309
+
300
310
  #: name by which the directive is called (auto...) and the default
301
311
  #: generated directive name
302
312
  objtype = 'object'
@@ -309,7 +319,7 @@ class Documenter:
309
319
  #: true if the generated content may contain titles
310
320
  titles_allowed = True
311
321
 
312
- option_spec: OptionSpec = {
322
+ option_spec: ClassVar[OptionSpec] = {
313
323
  'no-index': bool_option,
314
324
  'noindex': bool_option,
315
325
  }
@@ -319,8 +329,9 @@ class Documenter:
319
329
  return autodoc_attrgetter(self.env.app, obj, name, *defargs)
320
330
 
321
331
  @classmethod
322
- def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any,
323
- ) -> bool:
332
+ def can_document_member(
333
+ cls: type[Documenter], member: Any, membername: str, isattr: bool, parent: Any,
334
+ ) -> bool:
324
335
  """Called to see if a member can be documented by this Documenter."""
325
336
  msg = 'must be implemented in subclasses'
326
337
  raise NotImplementedError(msg)
@@ -450,9 +461,7 @@ class Documenter:
450
461
 
451
462
  subject = inspect.unpartial(self.object)
452
463
  modname = self.get_attr(subject, '__module__', None)
453
- if modname and modname != self.modname:
454
- return False
455
- return True
464
+ return not modname or modname == self.modname
456
465
 
457
466
  def format_args(self, **kwargs: Any) -> str:
458
467
  """Format the argument signature of *self.object*.
@@ -923,7 +932,7 @@ class Documenter:
923
932
  except PycodeError:
924
933
  pass
925
934
 
926
- docstrings: list[str] = sum(self.get_doc() or [], [])
935
+ docstrings: list[str] = functools.reduce(operator.iadd, self.get_doc() or [], [])
927
936
  if ismock(self.object) and not docstrings:
928
937
  logger.warning(__('A mocked object is detected: %r'),
929
938
  self.name, type='autodoc')
@@ -966,11 +975,12 @@ class ModuleDocumenter(Documenter):
966
975
  """
967
976
  Specialized Documenter subclass for modules.
968
977
  """
978
+
969
979
  objtype = 'module'
970
980
  content_indent = ''
971
981
  _extra_indent = ' '
972
982
 
973
- option_spec: OptionSpec = {
983
+ option_spec: ClassVar[OptionSpec] = {
974
984
  'members': members_option, 'undoc-members': bool_option,
975
985
  'no-index': bool_option, 'inherited-members': inherited_members_option,
976
986
  'show-inheritance': bool_option, 'synopsis': identity,
@@ -997,8 +1007,9 @@ class ModuleDocumenter(Documenter):
997
1007
  self.add_line(line, src[0], src[1])
998
1008
 
999
1009
  @classmethod
1000
- def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any,
1001
- ) -> bool:
1010
+ def can_document_member(
1011
+ cls: type[Documenter], member: Any, membername: str, isattr: bool, parent: Any,
1012
+ ) -> bool:
1002
1013
  # don't document submodules automatically
1003
1014
  return False
1004
1015
 
@@ -1127,13 +1138,14 @@ class ModuleLevelDocumenter(Documenter):
1127
1138
  Specialized Documenter subclass for objects on module level (functions,
1128
1139
  classes, data/constants).
1129
1140
  """
1141
+
1130
1142
  def resolve_name(self, modname: str | None, parents: Any, path: str, base: str,
1131
1143
  ) -> tuple[str | None, list[str]]:
1132
1144
  if modname is not None:
1133
- return modname, parents + [base]
1145
+ return modname, [*parents, base]
1134
1146
  if path:
1135
1147
  modname = path.rstrip('.')
1136
- return modname, parents + [base]
1148
+ return modname, [*parents, base]
1137
1149
 
1138
1150
  # if documenting a toplevel object without explicit module,
1139
1151
  # it can be contained in another auto directive ...
@@ -1142,7 +1154,7 @@ class ModuleLevelDocumenter(Documenter):
1142
1154
  if not modname:
1143
1155
  modname = self.env.ref_context.get('py:module')
1144
1156
  # ... else, it stays None, which means invalid
1145
- return modname, parents + [base]
1157
+ return modname, [*parents, base]
1146
1158
 
1147
1159
 
1148
1160
  class ClassLevelDocumenter(Documenter):
@@ -1150,10 +1162,11 @@ class ClassLevelDocumenter(Documenter):
1150
1162
  Specialized Documenter subclass for objects on class level (methods,
1151
1163
  attributes).
1152
1164
  """
1165
+
1153
1166
  def resolve_name(self, modname: str | None, parents: Any, path: str, base: str,
1154
1167
  ) -> tuple[str | None, list[str]]:
1155
1168
  if modname is not None:
1156
- return modname, parents + [base]
1169
+ return modname, [*parents, base]
1157
1170
 
1158
1171
  if path:
1159
1172
  mod_cls = path.rstrip('.')
@@ -1177,7 +1190,7 @@ class ClassLevelDocumenter(Documenter):
1177
1190
  if not modname:
1178
1191
  modname = self.env.ref_context.get('py:module')
1179
1192
  # ... else, it stays None, which means invalid
1180
- return modname, parents + [base]
1193
+ return modname, [*parents, base]
1181
1194
 
1182
1195
 
1183
1196
  class DocstringSignatureMixin:
@@ -1185,6 +1198,7 @@ class DocstringSignatureMixin:
1185
1198
  Mixin for FunctionDocumenter and MethodDocumenter to provide the
1186
1199
  feature of reading the signature from the docstring.
1187
1200
  """
1201
+
1188
1202
  _new_docstrings: list[list[str]] | None = None
1189
1203
  _signatures: list[str] = []
1190
1204
 
@@ -1256,7 +1270,7 @@ class DocstringSignatureMixin:
1256
1270
  self.args, self.retann = result
1257
1271
  sig = super().format_signature(**kwargs) # type: ignore[misc]
1258
1272
  if self._signatures:
1259
- return "\n".join([sig] + self._signatures)
1273
+ return "\n".join((sig, *self._signatures))
1260
1274
  else:
1261
1275
  return sig
1262
1276
 
@@ -1266,6 +1280,7 @@ class DocstringStripSignatureMixin(DocstringSignatureMixin):
1266
1280
  Mixin for AttributeDocumenter to provide the
1267
1281
  feature of stripping any function signature from the docstring.
1268
1282
  """
1283
+
1269
1284
  def format_signature(self, **kwargs: Any) -> str:
1270
1285
  if (
1271
1286
  self.args is None
@@ -1286,12 +1301,14 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ
1286
1301
  """
1287
1302
  Specialized Documenter subclass for functions.
1288
1303
  """
1304
+
1289
1305
  objtype = 'function'
1290
1306
  member_order = 30
1291
1307
 
1292
1308
  @classmethod
1293
- def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any,
1294
- ) -> bool:
1309
+ def can_document_member(
1310
+ cls: type[Documenter], member: Any, membername: str, isattr: bool, parent: Any,
1311
+ ) -> bool:
1295
1312
  # supports functions, builtins and bound methods exported at the module level
1296
1313
  return (inspect.isfunction(member) or inspect.isbuiltin(member) or
1297
1314
  (inspect.isroutine(member) and isinstance(parent, ModuleDocumenter)))
@@ -1393,7 +1410,7 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ
1393
1410
  if len(sig.parameters) == 0:
1394
1411
  return None
1395
1412
 
1396
- def dummy():
1413
+ def dummy(): # NoQA: ANN202
1397
1414
  pass
1398
1415
 
1399
1416
  params = list(sig.parameters.values())
@@ -1414,6 +1431,7 @@ class DecoratorDocumenter(FunctionDocumenter):
1414
1431
  """
1415
1432
  Specialized Documenter subclass for decorator functions.
1416
1433
  """
1434
+
1417
1435
  objtype = 'decorator'
1418
1436
 
1419
1437
  # must be lower than FunctionDocumenter
@@ -1445,9 +1463,10 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
1445
1463
  """
1446
1464
  Specialized Documenter subclass for classes.
1447
1465
  """
1466
+
1448
1467
  objtype = 'class'
1449
1468
  member_order = 20
1450
- option_spec: OptionSpec = {
1469
+ option_spec: ClassVar[OptionSpec] = {
1451
1470
  'members': members_option, 'undoc-members': bool_option,
1452
1471
  'no-index': bool_option, 'inherited-members': inherited_members_option,
1453
1472
  'show-inheritance': bool_option, 'member-order': member_order_option,
@@ -1481,8 +1500,9 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
1481
1500
  merge_members_option(self.options)
1482
1501
 
1483
1502
  @classmethod
1484
- def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any,
1485
- ) -> bool:
1503
+ def can_document_member(
1504
+ cls: type[Documenter], member: Any, membername: str, isattr: bool, parent: Any,
1505
+ ) -> bool:
1486
1506
  return isinstance(member, type) or (
1487
1507
  isattr and (inspect.isNewType(member) or isinstance(member, TypeVar)))
1488
1508
 
@@ -1509,7 +1529,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
1509
1529
  return None, None, None
1510
1530
 
1511
1531
  def get_user_defined_function_or_method(obj: Any, attr: str) -> Any:
1512
- """ Get the `attr` function or method from `obj`, if it is user-defined. """
1532
+ """Get the `attr` function or method from `obj`, if it is user-defined."""
1513
1533
  if inspect.is_builtin_class_method(obj, attr):
1514
1534
  return None
1515
1535
  attr = self.get_attr(obj, attr, None)
@@ -1657,7 +1677,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
1657
1677
  try:
1658
1678
  analyzer = ModuleAnalyzer.for_module(cls.__module__)
1659
1679
  analyzer.analyze()
1660
- qualname = '.'.join([cls.__qualname__, self._signature_method_name])
1680
+ qualname = f'{cls.__qualname__}.{self._signature_method_name}'
1661
1681
  if qualname in analyzer.overloads:
1662
1682
  return analyzer.overloads.get(qualname, [])
1663
1683
  elif qualname in analyzer.tagorder:
@@ -1678,7 +1698,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
1678
1698
  __qualname__ = None
1679
1699
 
1680
1700
  if __modname__ and __qualname__:
1681
- return '.'.join([__modname__, __qualname__])
1701
+ return f'{__modname__}.{__qualname__}'
1682
1702
  else:
1683
1703
  return None
1684
1704
 
@@ -1904,6 +1924,7 @@ class ExceptionDocumenter(ClassDocumenter):
1904
1924
  """
1905
1925
  Specialized ClassDocumenter subclass for exceptions.
1906
1926
  """
1927
+
1907
1928
  objtype = 'exception'
1908
1929
  member_order = 10
1909
1930
 
@@ -1911,8 +1932,9 @@ class ExceptionDocumenter(ClassDocumenter):
1911
1932
  priority = ClassDocumenter.priority + 5
1912
1933
 
1913
1934
  @classmethod
1914
- def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any,
1915
- ) -> bool:
1935
+ def can_document_member(
1936
+ cls: type[Documenter], member: Any, membername: str, isattr: bool, parent: Any,
1937
+ ) -> bool:
1916
1938
  try:
1917
1939
  return isinstance(member, type) and issubclass(member, BaseException)
1918
1940
  except TypeError as exc:
@@ -2016,16 +2038,18 @@ class DataDocumenter(GenericAliasMixin,
2016
2038
  """
2017
2039
  Specialized Documenter subclass for data items.
2018
2040
  """
2041
+
2019
2042
  objtype = 'data'
2020
2043
  member_order = 40
2021
2044
  priority = -10
2022
- option_spec: OptionSpec = dict(ModuleLevelDocumenter.option_spec)
2045
+ option_spec: ClassVar[OptionSpec] = dict(ModuleLevelDocumenter.option_spec)
2023
2046
  option_spec["annotation"] = annotation_option
2024
2047
  option_spec["no-value"] = bool_option
2025
2048
 
2026
2049
  @classmethod
2027
- def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any,
2028
- ) -> bool:
2050
+ def can_document_member(
2051
+ cls: type[Documenter], member: Any, membername: str, isattr: bool, parent: Any,
2052
+ ) -> bool:
2029
2053
  return isinstance(parent, ModuleDocumenter) and isattr
2030
2054
 
2031
2055
  def update_annotations(self, parent: Any) -> None:
@@ -2054,7 +2078,8 @@ class DataDocumenter(GenericAliasMixin,
2054
2078
  return True
2055
2079
  else:
2056
2080
  doc = self.get_doc() or []
2057
- docstring, metadata = separate_metadata('\n'.join(sum(doc, [])))
2081
+ docstring, metadata = separate_metadata(
2082
+ '\n'.join(functools.reduce(operator.iadd, doc, [])))
2058
2083
  if 'hide-value' in metadata:
2059
2084
  return True
2060
2085
 
@@ -2135,14 +2160,16 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
2135
2160
  """
2136
2161
  Specialized Documenter subclass for methods (normal, static and class).
2137
2162
  """
2163
+
2138
2164
  objtype = 'method'
2139
2165
  directivetype = 'method'
2140
2166
  member_order = 50
2141
2167
  priority = 1 # must be more than FunctionDocumenter
2142
2168
 
2143
2169
  @classmethod
2144
- def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any,
2145
- ) -> bool:
2170
+ def can_document_member(
2171
+ cls: type[Documenter], member: Any, membername: str, isattr: bool, parent: Any,
2172
+ ) -> bool:
2146
2173
  return inspect.isroutine(member) and not isinstance(parent, ModuleDocumenter)
2147
2174
 
2148
2175
  def import_object(self, raiseerror: bool = False) -> bool:
@@ -2169,7 +2196,7 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
2169
2196
  kwargs.setdefault('unqualified_typehints', True)
2170
2197
 
2171
2198
  try:
2172
- if self.object == object.__init__ and self.parent != object:
2199
+ if self.object == object.__init__ and self.parent != object: # NoQA: E721
2173
2200
  # Classes not having own __init__() method are shown as no arguments.
2174
2201
  #
2175
2202
  # Note: The signature of object.__init__() is (self, /, *args, **kwargs).
@@ -2206,7 +2233,8 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
2206
2233
  self.add_line(' :abstractmethod:', sourcename)
2207
2234
  if inspect.iscoroutinefunction(obj) or inspect.isasyncgenfunction(obj):
2208
2235
  self.add_line(' :async:', sourcename)
2209
- if inspect.isclassmethod(obj):
2236
+ if (inspect.isclassmethod(obj) or
2237
+ inspect.is_singledispatch_method(obj) and inspect.isclassmethod(obj.func)):
2210
2238
  self.add_line(' :classmethod:', sourcename)
2211
2239
  if inspect.isstaticmethod(obj, cls=self.parent, name=self.object_name):
2212
2240
  self.add_line(' :staticmethod:', sourcename)
@@ -2238,6 +2266,8 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
2238
2266
  if typ is object:
2239
2267
  pass # default implementation. skipped.
2240
2268
  else:
2269
+ if inspect.isclassmethod(func):
2270
+ func = func.__func__
2241
2271
  dispatchmeth = self.annotate_to_first_argument(func, typ)
2242
2272
  if dispatchmeth:
2243
2273
  documenter = MethodDocumenter(self.directive, '')
@@ -2292,7 +2322,7 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
2292
2322
  if len(sig.parameters) == 1:
2293
2323
  return None
2294
2324
 
2295
- def dummy():
2325
+ def dummy(): # NoQA: ANN202
2296
2326
  pass
2297
2327
 
2298
2328
  params = list(sig.parameters.values())
@@ -2408,8 +2438,8 @@ class SlotsMixin(DataDocumenterMixinBase):
2408
2438
  if self.object is SLOTSATTR:
2409
2439
  try:
2410
2440
  parent___slots__ = inspect.getslots(self.parent)
2411
- if parent___slots__ and parent___slots__.get(self.objpath[-1]):
2412
- docstring = prepare_docstring(parent___slots__[self.objpath[-1]])
2441
+ if parent___slots__ and (docstring := parent___slots__.get(self.objpath[-1])):
2442
+ docstring = prepare_docstring(docstring)
2413
2443
  return [docstring]
2414
2444
  else:
2415
2445
  return []
@@ -2440,9 +2470,7 @@ class RuntimeInstanceAttributeMixin(DataDocumenterMixinBase):
2440
2470
  # An instance variable defined in __init__().
2441
2471
  if self.get_attribute_comment(parent, self.objpath[-1]): # type: ignore[attr-defined]
2442
2472
  return True
2443
- if self.is_runtime_instance_attribute_not_commented(parent):
2444
- return True
2445
- return False
2473
+ return self.is_runtime_instance_attribute_not_commented(parent)
2446
2474
 
2447
2475
  def is_runtime_instance_attribute_not_commented(self, parent: Any) -> bool:
2448
2476
  """Check the subject is an attribute defined in __init__() without comment."""
@@ -2454,7 +2482,7 @@ class RuntimeInstanceAttributeMixin(DataDocumenterMixinBase):
2454
2482
  analyzer = ModuleAnalyzer.for_module(module)
2455
2483
  analyzer.analyze()
2456
2484
  if qualname and self.objpath:
2457
- key = '.'.join([qualname, self.objpath[-1]])
2485
+ key = f'{qualname}.{self.objpath[-1]}'
2458
2486
  if key in analyzer.tagorder:
2459
2487
  return True
2460
2488
  except (AttributeError, PycodeError):
@@ -2464,7 +2492,8 @@ class RuntimeInstanceAttributeMixin(DataDocumenterMixinBase):
2464
2492
 
2465
2493
  def import_object(self, raiseerror: bool = False) -> bool:
2466
2494
  """Check the existence of runtime instance attribute after failing to import the
2467
- attribute."""
2495
+ attribute.
2496
+ """
2468
2497
  try:
2469
2498
  return super().import_object(raiseerror=True) # type: ignore[misc]
2470
2499
  except ImportError as exc:
@@ -2517,7 +2546,8 @@ class UninitializedInstanceAttributeMixin(DataDocumenterMixinBase):
2517
2546
 
2518
2547
  def import_object(self, raiseerror: bool = False) -> bool:
2519
2548
  """Check the exisitence of uninitialized instance attribute when failed to import
2520
- the attribute."""
2549
+ the attribute.
2550
+ """
2521
2551
  try:
2522
2552
  return super().import_object(raiseerror=True) # type: ignore[misc]
2523
2553
  except ImportError as exc:
@@ -2556,9 +2586,10 @@ class AttributeDocumenter(GenericAliasMixin, SlotsMixin, # type: ignore[misc]
2556
2586
  """
2557
2587
  Specialized Documenter subclass for attributes.
2558
2588
  """
2589
+
2559
2590
  objtype = 'attribute'
2560
2591
  member_order = 60
2561
- option_spec: OptionSpec = dict(ModuleLevelDocumenter.option_spec)
2592
+ option_spec: ClassVar[OptionSpec] = dict(ModuleLevelDocumenter.option_spec)
2562
2593
  option_spec["annotation"] = annotation_option
2563
2594
  option_spec["no-value"] = bool_option
2564
2595
 
@@ -2571,15 +2602,14 @@ class AttributeDocumenter(GenericAliasMixin, SlotsMixin, # type: ignore[misc]
2571
2602
  return inspect.isfunction(obj) or inspect.isbuiltin(obj) or inspect.ismethod(obj)
2572
2603
 
2573
2604
  @classmethod
2574
- def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any,
2575
- ) -> bool:
2605
+ def can_document_member(
2606
+ cls: type[Documenter], member: Any, membername: str, isattr: bool, parent: Any,
2607
+ ) -> bool:
2576
2608
  if isinstance(parent, ModuleDocumenter):
2577
2609
  return False
2578
2610
  if inspect.isattributedescriptor(member):
2579
2611
  return True
2580
- if not inspect.isroutine(member) and not isinstance(member, type):
2581
- return True
2582
- return False
2612
+ return not inspect.isroutine(member) and not isinstance(member, type)
2583
2613
 
2584
2614
  def document_members(self, all_members: bool = False) -> None:
2585
2615
  pass
@@ -2625,7 +2655,8 @@ class AttributeDocumenter(GenericAliasMixin, SlotsMixin, # type: ignore[misc]
2625
2655
  else:
2626
2656
  doc = self.get_doc()
2627
2657
  if doc:
2628
- docstring, metadata = separate_metadata('\n'.join(sum(doc, [])))
2658
+ docstring, metadata = separate_metadata(
2659
+ '\n'.join(functools.reduce(operator.iadd, doc, [])))
2629
2660
  if 'hide-value' in metadata:
2630
2661
  return True
2631
2662
 
@@ -2711,6 +2742,7 @@ class PropertyDocumenter(DocstringStripSignatureMixin, # type: ignore[misc]
2711
2742
  """
2712
2743
  Specialized Documenter subclass for properties.
2713
2744
  """
2745
+
2714
2746
  objtype = 'property'
2715
2747
  member_order = 60
2716
2748
 
@@ -2718,8 +2750,9 @@ class PropertyDocumenter(DocstringStripSignatureMixin, # type: ignore[misc]
2718
2750
  priority = AttributeDocumenter.priority + 1
2719
2751
 
2720
2752
  @classmethod
2721
- def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any,
2722
- ) -> bool:
2753
+ def can_document_member(
2754
+ cls: type[Documenter], member: Any, membername: str, isattr: bool, parent: Any,
2755
+ ) -> bool:
2723
2756
  if isinstance(parent, ClassDocumenter):
2724
2757
  if inspect.isproperty(member):
2725
2758
  return True
@@ -2732,7 +2765,8 @@ class PropertyDocumenter(DocstringStripSignatureMixin, # type: ignore[misc]
2732
2765
 
2733
2766
  def import_object(self, raiseerror: bool = False) -> bool:
2734
2767
  """Check the exisitence of uninitialized instance attribute when failed to import
2735
- the attribute."""
2768
+ the attribute.
2769
+ """
2736
2770
  ret = super().import_object(raiseerror)
2737
2771
  if ret and not inspect.isproperty(self.object):
2738
2772
  __dict__ = safe_getattr(self.parent, '__dict__', {})
@@ -2793,7 +2827,7 @@ class PropertyDocumenter(DocstringStripSignatureMixin, # type: ignore[misc]
2793
2827
  except ValueError:
2794
2828
  pass
2795
2829
 
2796
- def _get_property_getter(self):
2830
+ def _get_property_getter(self) -> Callable | None:
2797
2831
  if safe_getattr(self.object, 'fget', None): # property
2798
2832
  return self.object.fget
2799
2833
  if safe_getattr(self.object, 'func', None): # cached_property
@@ -2810,7 +2844,7 @@ def autodoc_attrgetter(app: Sphinx, obj: Any, name: str, *defargs: Any) -> Any:
2810
2844
  return safe_getattr(obj, name, *defargs)
2811
2845
 
2812
2846
 
2813
- def setup(app: Sphinx) -> dict[str, Any]:
2847
+ def setup(app: Sphinx) -> ExtensionMetadata:
2814
2848
  app.add_autodocumenter(ModuleDocumenter)
2815
2849
  app.add_autodocumenter(ClassDocumenter)
2816
2850
  app.add_autodocumenter(ExceptionDocumenter)
@@ -2821,22 +2855,22 @@ def setup(app: Sphinx) -> dict[str, Any]:
2821
2855
  app.add_autodocumenter(AttributeDocumenter)
2822
2856
  app.add_autodocumenter(PropertyDocumenter)
2823
2857
 
2824
- app.add_config_value('autoclass_content', 'class', True, ENUM('both', 'class', 'init'))
2825
- app.add_config_value('autodoc_member_order', 'alphabetical', True,
2858
+ app.add_config_value('autoclass_content', 'class', 'env', ENUM('both', 'class', 'init'))
2859
+ app.add_config_value('autodoc_member_order', 'alphabetical', 'env',
2826
2860
  ENUM('alphabetical', 'bysource', 'groupwise'))
2827
- app.add_config_value('autodoc_class_signature', 'mixed', True, ENUM('mixed', 'separated'))
2828
- app.add_config_value('autodoc_default_options', {}, True)
2829
- app.add_config_value('autodoc_docstring_signature', True, True)
2830
- app.add_config_value('autodoc_mock_imports', [], True)
2831
- app.add_config_value('autodoc_typehints', "signature", True,
2861
+ app.add_config_value('autodoc_class_signature', 'mixed', 'env', ENUM('mixed', 'separated'))
2862
+ app.add_config_value('autodoc_default_options', {}, 'env')
2863
+ app.add_config_value('autodoc_docstring_signature', True, 'env')
2864
+ app.add_config_value('autodoc_mock_imports', [], 'env')
2865
+ app.add_config_value('autodoc_typehints', "signature", 'env',
2832
2866
  ENUM("signature", "description", "none", "both"))
2833
- app.add_config_value('autodoc_typehints_description_target', 'all', True,
2867
+ app.add_config_value('autodoc_typehints_description_target', 'all', 'env',
2834
2868
  ENUM('all', 'documented', 'documented_params'))
2835
- app.add_config_value('autodoc_type_aliases', {}, True)
2869
+ app.add_config_value('autodoc_type_aliases', {}, 'env')
2836
2870
  app.add_config_value('autodoc_typehints_format', "short", 'env',
2837
2871
  ENUM("fully-qualified", "short"))
2838
- app.add_config_value('autodoc_warningiserror', True, True)
2839
- app.add_config_value('autodoc_inherit_docstrings', True, True)
2872
+ app.add_config_value('autodoc_warningiserror', True, 'env')
2873
+ app.add_config_value('autodoc_inherit_docstrings', True, 'env')
2840
2874
  app.add_event('autodoc-before-process-signature')
2841
2875
  app.add_event('autodoc-process-docstring')
2842
2876
  app.add_event('autodoc-process-signature')
@@ -59,20 +59,20 @@ class DocumenterBridge:
59
59
  def process_documenter_options(documenter: type[Documenter], config: Config, options: dict,
60
60
  ) -> Options:
61
61
  """Recognize options of Documenter from user input."""
62
+ default_options = config.autodoc_default_options
62
63
  for name in AUTODOC_DEFAULT_OPTIONS:
63
64
  if name not in documenter.option_spec:
64
65
  continue
65
66
  negated = options.pop('no-' + name, True) is None
66
- if name in config.autodoc_default_options and not negated:
67
- if name in options and isinstance(config.autodoc_default_options[name], str):
67
+ if name in default_options and not negated:
68
+ if name in options and isinstance(default_options[name], str):
68
69
  # take value from options if present or extend it
69
70
  # with autodoc_default_options if necessary
70
71
  if name in AUTODOC_EXTENDABLE_OPTIONS:
71
72
  if options[name] is not None and options[name].startswith('+'):
72
- options[name] = ','.join([config.autodoc_default_options[name],
73
- options[name][1:]])
73
+ options[name] = f'{default_options[name]},{options[name][1:]}'
74
74
  else:
75
- options[name] = config.autodoc_default_options[name]
75
+ options[name] = default_options[name]
76
76
 
77
77
  elif options.get(name) is not None:
78
78
  # remove '+' from option argument if there's nothing to merge it with
@@ -104,6 +104,7 @@ class AutodocDirective(SphinxDirective):
104
104
  It invokes a Documenter upon running. After the processing, it parses and returns
105
105
  the content generated by Documenter.
106
106
  """
107
+
107
108
  option_spec = DummyOptionSpec()
108
109
  has_content = True
109
110
  required_arguments = 1
@@ -114,7 +115,7 @@ class AutodocDirective(SphinxDirective):
114
115
  reporter = self.state.document.reporter
115
116
 
116
117
  try:
117
- source, lineno = reporter.get_source_and_line( # type: ignore[attr-defined]
118
+ source, lineno = reporter.get_source_and_line(
118
119
  self.lineno)
119
120
  except AttributeError:
120
121
  source, lineno = (None, None)