Sphinx 7.3.6__py3-none-any.whl → 7.4.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 (357) hide show
  1. sphinx/__init__.py +5 -6
  2. sphinx/_cli/__init__.py +296 -0
  3. sphinx/_cli/util/__init__.py +0 -0
  4. sphinx/_cli/util/colour.py +103 -0
  5. sphinx/_cli/util/errors.py +165 -0
  6. sphinx/application.py +78 -43
  7. sphinx/builders/__init__.py +59 -15
  8. sphinx/builders/_epub_base.py +11 -5
  9. sphinx/builders/changes.py +2 -2
  10. sphinx/builders/epub3.py +2 -2
  11. sphinx/builders/gettext.py +10 -10
  12. sphinx/builders/html/__init__.py +56 -54
  13. sphinx/builders/latex/__init__.py +5 -5
  14. sphinx/builders/latex/constants.py +5 -0
  15. sphinx/builders/linkcheck.py +73 -38
  16. sphinx/builders/texinfo.py +1 -1
  17. sphinx/cmd/build.py +1 -1
  18. sphinx/cmd/quickstart.py +11 -11
  19. sphinx/config.py +57 -38
  20. sphinx/directives/__init__.py +7 -9
  21. sphinx/directives/code.py +12 -15
  22. sphinx/directives/other.py +12 -15
  23. sphinx/directives/patches.py +26 -0
  24. sphinx/domains/__init__.py +1 -1
  25. sphinx/domains/c/__init__.py +5 -5
  26. sphinx/domains/c/_ast.py +436 -12
  27. sphinx/domains/c/_symbol.py +89 -134
  28. sphinx/domains/changeset.py +3 -4
  29. sphinx/domains/cpp/__init__.py +5 -6
  30. sphinx/domains/cpp/_ast.py +822 -25
  31. sphinx/domains/cpp/_symbol.py +3 -0
  32. sphinx/domains/javascript.py +3 -6
  33. sphinx/domains/math.py +3 -2
  34. sphinx/domains/python/__init__.py +45 -6
  35. sphinx/domains/python/_object.py +7 -5
  36. sphinx/domains/rst.py +2 -2
  37. sphinx/domains/std/__init__.py +95 -14
  38. sphinx/environment/__init__.py +35 -15
  39. sphinx/environment/adapters/indexentries.py +71 -24
  40. sphinx/environment/adapters/toctree.py +1 -1
  41. sphinx/environment/collectors/__init__.py +18 -4
  42. sphinx/environment/collectors/asset.py +4 -4
  43. sphinx/environment/collectors/toctree.py +27 -14
  44. sphinx/events.py +7 -6
  45. sphinx/ext/apidoc.py +377 -170
  46. sphinx/ext/autodoc/__init__.py +13 -13
  47. sphinx/ext/autodoc/directive.py +10 -13
  48. sphinx/ext/autodoc/mock.py +10 -7
  49. sphinx/ext/autodoc/preserve_defaults.py +1 -1
  50. sphinx/ext/autodoc/typehints.py +2 -2
  51. sphinx/ext/autosummary/__init__.py +15 -9
  52. sphinx/ext/autosummary/generate.py +270 -154
  53. sphinx/ext/coverage.py +108 -18
  54. sphinx/ext/duration.py +10 -3
  55. sphinx/ext/extlinks.py +3 -2
  56. sphinx/ext/graphviz.py +3 -3
  57. sphinx/ext/ifconfig.py +1 -2
  58. sphinx/ext/imgconverter.py +1 -0
  59. sphinx/ext/imgmath.py +7 -6
  60. sphinx/ext/inheritance_diagram.py +3 -3
  61. sphinx/ext/intersphinx/__init__.py +81 -0
  62. sphinx/ext/intersphinx/__main__.py +10 -0
  63. sphinx/ext/intersphinx/_cli.py +44 -0
  64. sphinx/ext/intersphinx/_load.py +253 -0
  65. sphinx/ext/{intersphinx.py → intersphinx/_resolve.py} +17 -368
  66. sphinx/ext/intersphinx/_shared.py +53 -0
  67. sphinx/ext/mathjax.py +1 -1
  68. sphinx/ext/todo.py +2 -2
  69. sphinx/io.py +2 -6
  70. sphinx/locale/__init__.py +1 -5
  71. sphinx/locale/ar/LC_MESSAGES/sphinx.js +1 -1
  72. sphinx/locale/ar/LC_MESSAGES/sphinx.mo +0 -0
  73. sphinx/locale/ar/LC_MESSAGES/sphinx.po +678 -471
  74. sphinx/locale/bg/LC_MESSAGES/sphinx.js +1 -1
  75. sphinx/locale/bg/LC_MESSAGES/sphinx.mo +0 -0
  76. sphinx/locale/bg/LC_MESSAGES/sphinx.po +684 -476
  77. sphinx/locale/bn/LC_MESSAGES/sphinx.js +1 -1
  78. sphinx/locale/bn/LC_MESSAGES/sphinx.mo +0 -0
  79. sphinx/locale/bn/LC_MESSAGES/sphinx.po +679 -472
  80. sphinx/locale/ca/LC_MESSAGES/sphinx.js +1 -1
  81. sphinx/locale/ca/LC_MESSAGES/sphinx.mo +0 -0
  82. sphinx/locale/ca/LC_MESSAGES/sphinx.po +681 -474
  83. sphinx/locale/cak/LC_MESSAGES/sphinx.js +1 -1
  84. sphinx/locale/cak/LC_MESSAGES/sphinx.mo +0 -0
  85. sphinx/locale/cak/LC_MESSAGES/sphinx.po +678 -471
  86. sphinx/locale/cs/LC_MESSAGES/sphinx.js +1 -1
  87. sphinx/locale/cs/LC_MESSAGES/sphinx.mo +0 -0
  88. sphinx/locale/cs/LC_MESSAGES/sphinx.po +679 -472
  89. sphinx/locale/cy/LC_MESSAGES/sphinx.js +1 -1
  90. sphinx/locale/cy/LC_MESSAGES/sphinx.mo +0 -0
  91. sphinx/locale/cy/LC_MESSAGES/sphinx.po +679 -472
  92. sphinx/locale/da/LC_MESSAGES/sphinx.js +1 -1
  93. sphinx/locale/da/LC_MESSAGES/sphinx.mo +0 -0
  94. sphinx/locale/da/LC_MESSAGES/sphinx.po +679 -472
  95. sphinx/locale/de/LC_MESSAGES/sphinx.js +1 -1
  96. sphinx/locale/de/LC_MESSAGES/sphinx.mo +0 -0
  97. sphinx/locale/de/LC_MESSAGES/sphinx.po +679 -472
  98. sphinx/locale/de_DE/LC_MESSAGES/sphinx.js +1 -1
  99. sphinx/locale/de_DE/LC_MESSAGES/sphinx.mo +0 -0
  100. sphinx/locale/de_DE/LC_MESSAGES/sphinx.po +678 -471
  101. sphinx/locale/el/LC_MESSAGES/sphinx.js +1 -1
  102. sphinx/locale/el/LC_MESSAGES/sphinx.mo +0 -0
  103. sphinx/locale/el/LC_MESSAGES/sphinx.po +701 -494
  104. sphinx/locale/en_DE/LC_MESSAGES/sphinx.js +1 -1
  105. sphinx/locale/en_DE/LC_MESSAGES/sphinx.mo +0 -0
  106. sphinx/locale/en_DE/LC_MESSAGES/sphinx.po +700 -493
  107. sphinx/locale/en_FR/LC_MESSAGES/sphinx.js +1 -1
  108. sphinx/locale/en_FR/LC_MESSAGES/sphinx.mo +0 -0
  109. sphinx/locale/en_FR/LC_MESSAGES/sphinx.po +700 -493
  110. sphinx/locale/en_GB/LC_MESSAGES/sphinx.js +1 -1
  111. sphinx/locale/en_GB/LC_MESSAGES/sphinx.mo +0 -0
  112. sphinx/locale/en_GB/LC_MESSAGES/sphinx.po +701 -494
  113. sphinx/locale/en_HK/LC_MESSAGES/sphinx.js +1 -1
  114. sphinx/locale/en_HK/LC_MESSAGES/sphinx.mo +0 -0
  115. sphinx/locale/en_HK/LC_MESSAGES/sphinx.po +700 -493
  116. sphinx/locale/eo/LC_MESSAGES/sphinx.js +1 -1
  117. sphinx/locale/eo/LC_MESSAGES/sphinx.mo +0 -0
  118. sphinx/locale/eo/LC_MESSAGES/sphinx.po +701 -494
  119. sphinx/locale/es/LC_MESSAGES/sphinx.js +1 -1
  120. sphinx/locale/es/LC_MESSAGES/sphinx.mo +0 -0
  121. sphinx/locale/es/LC_MESSAGES/sphinx.po +701 -494
  122. sphinx/locale/es_CO/LC_MESSAGES/sphinx.js +1 -1
  123. sphinx/locale/es_CO/LC_MESSAGES/sphinx.mo +0 -0
  124. sphinx/locale/es_CO/LC_MESSAGES/sphinx.po +700 -493
  125. sphinx/locale/et/LC_MESSAGES/sphinx.js +1 -1
  126. sphinx/locale/et/LC_MESSAGES/sphinx.mo +0 -0
  127. sphinx/locale/et/LC_MESSAGES/sphinx.po +701 -494
  128. sphinx/locale/eu/LC_MESSAGES/sphinx.js +1 -1
  129. sphinx/locale/eu/LC_MESSAGES/sphinx.mo +0 -0
  130. sphinx/locale/eu/LC_MESSAGES/sphinx.po +701 -494
  131. sphinx/locale/fa/LC_MESSAGES/sphinx.js +1 -1
  132. sphinx/locale/fa/LC_MESSAGES/sphinx.mo +0 -0
  133. sphinx/locale/fa/LC_MESSAGES/sphinx.po +701 -494
  134. sphinx/locale/fi/LC_MESSAGES/sphinx.js +1 -1
  135. sphinx/locale/fi/LC_MESSAGES/sphinx.mo +0 -0
  136. sphinx/locale/fi/LC_MESSAGES/sphinx.po +700 -493
  137. sphinx/locale/fr/LC_MESSAGES/sphinx.js +1 -1
  138. sphinx/locale/fr/LC_MESSAGES/sphinx.mo +0 -0
  139. sphinx/locale/fr/LC_MESSAGES/sphinx.po +725 -518
  140. sphinx/locale/fr_FR/LC_MESSAGES/sphinx.js +1 -1
  141. sphinx/locale/fr_FR/LC_MESSAGES/sphinx.mo +0 -0
  142. sphinx/locale/fr_FR/LC_MESSAGES/sphinx.po +700 -493
  143. sphinx/locale/gl/LC_MESSAGES/sphinx.js +1 -1
  144. sphinx/locale/gl/LC_MESSAGES/sphinx.mo +0 -0
  145. sphinx/locale/gl/LC_MESSAGES/sphinx.po +701 -494
  146. sphinx/locale/he/LC_MESSAGES/sphinx.js +1 -1
  147. sphinx/locale/he/LC_MESSAGES/sphinx.mo +0 -0
  148. sphinx/locale/he/LC_MESSAGES/sphinx.po +700 -493
  149. sphinx/locale/hi/LC_MESSAGES/sphinx.js +1 -1
  150. sphinx/locale/hi/LC_MESSAGES/sphinx.mo +0 -0
  151. sphinx/locale/hi/LC_MESSAGES/sphinx.po +701 -494
  152. sphinx/locale/hi_IN/LC_MESSAGES/sphinx.js +1 -1
  153. sphinx/locale/hi_IN/LC_MESSAGES/sphinx.mo +0 -0
  154. sphinx/locale/hi_IN/LC_MESSAGES/sphinx.po +700 -493
  155. sphinx/locale/hr/LC_MESSAGES/sphinx.js +1 -1
  156. sphinx/locale/hr/LC_MESSAGES/sphinx.mo +0 -0
  157. sphinx/locale/hr/LC_MESSAGES/sphinx.po +701 -494
  158. sphinx/locale/hu/LC_MESSAGES/sphinx.js +1 -1
  159. sphinx/locale/hu/LC_MESSAGES/sphinx.mo +0 -0
  160. sphinx/locale/hu/LC_MESSAGES/sphinx.po +701 -494
  161. sphinx/locale/id/LC_MESSAGES/sphinx.js +1 -1
  162. sphinx/locale/id/LC_MESSAGES/sphinx.mo +0 -0
  163. sphinx/locale/id/LC_MESSAGES/sphinx.po +701 -494
  164. sphinx/locale/is/LC_MESSAGES/sphinx.js +1 -1
  165. sphinx/locale/is/LC_MESSAGES/sphinx.mo +0 -0
  166. sphinx/locale/is/LC_MESSAGES/sphinx.po +700 -493
  167. sphinx/locale/it/LC_MESSAGES/sphinx.js +1 -1
  168. sphinx/locale/it/LC_MESSAGES/sphinx.mo +0 -0
  169. sphinx/locale/it/LC_MESSAGES/sphinx.po +708 -500
  170. sphinx/locale/ja/LC_MESSAGES/sphinx.js +1 -1
  171. sphinx/locale/ja/LC_MESSAGES/sphinx.mo +0 -0
  172. sphinx/locale/ja/LC_MESSAGES/sphinx.po +701 -494
  173. sphinx/locale/ka/LC_MESSAGES/sphinx.js +1 -1
  174. sphinx/locale/ka/LC_MESSAGES/sphinx.mo +0 -0
  175. sphinx/locale/ka/LC_MESSAGES/sphinx.po +700 -493
  176. sphinx/locale/ko/LC_MESSAGES/sphinx.js +1 -1
  177. sphinx/locale/ko/LC_MESSAGES/sphinx.mo +0 -0
  178. sphinx/locale/ko/LC_MESSAGES/sphinx.po +701 -494
  179. sphinx/locale/lt/LC_MESSAGES/sphinx.js +1 -1
  180. sphinx/locale/lt/LC_MESSAGES/sphinx.mo +0 -0
  181. sphinx/locale/lt/LC_MESSAGES/sphinx.po +701 -494
  182. sphinx/locale/lv/LC_MESSAGES/sphinx.js +1 -1
  183. sphinx/locale/lv/LC_MESSAGES/sphinx.mo +0 -0
  184. sphinx/locale/lv/LC_MESSAGES/sphinx.po +701 -494
  185. sphinx/locale/mk/LC_MESSAGES/sphinx.js +1 -1
  186. sphinx/locale/mk/LC_MESSAGES/sphinx.mo +0 -0
  187. sphinx/locale/mk/LC_MESSAGES/sphinx.po +700 -493
  188. sphinx/locale/nb_NO/LC_MESSAGES/sphinx.js +1 -1
  189. sphinx/locale/nb_NO/LC_MESSAGES/sphinx.mo +0 -0
  190. sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po +701 -494
  191. sphinx/locale/ne/LC_MESSAGES/sphinx.js +1 -1
  192. sphinx/locale/ne/LC_MESSAGES/sphinx.mo +0 -0
  193. sphinx/locale/ne/LC_MESSAGES/sphinx.po +701 -494
  194. sphinx/locale/nl/LC_MESSAGES/sphinx.js +1 -1
  195. sphinx/locale/nl/LC_MESSAGES/sphinx.mo +0 -0
  196. sphinx/locale/nl/LC_MESSAGES/sphinx.po +701 -494
  197. sphinx/locale/pl/LC_MESSAGES/sphinx.js +1 -1
  198. sphinx/locale/pl/LC_MESSAGES/sphinx.mo +0 -0
  199. sphinx/locale/pl/LC_MESSAGES/sphinx.po +701 -494
  200. sphinx/locale/pt/LC_MESSAGES/sphinx.js +1 -1
  201. sphinx/locale/pt/LC_MESSAGES/sphinx.mo +0 -0
  202. sphinx/locale/pt/LC_MESSAGES/sphinx.po +700 -493
  203. sphinx/locale/pt_BR/LC_MESSAGES/sphinx.js +1 -1
  204. sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo +0 -0
  205. sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po +705 -498
  206. sphinx/locale/pt_PT/LC_MESSAGES/sphinx.js +1 -1
  207. sphinx/locale/pt_PT/LC_MESSAGES/sphinx.mo +0 -0
  208. sphinx/locale/pt_PT/LC_MESSAGES/sphinx.po +701 -494
  209. sphinx/locale/ro/LC_MESSAGES/sphinx.js +1 -1
  210. sphinx/locale/ro/LC_MESSAGES/sphinx.mo +0 -0
  211. sphinx/locale/ro/LC_MESSAGES/sphinx.po +701 -494
  212. sphinx/locale/ru/LC_MESSAGES/sphinx.js +1 -1
  213. sphinx/locale/ru/LC_MESSAGES/sphinx.mo +0 -0
  214. sphinx/locale/ru/LC_MESSAGES/sphinx.po +890 -680
  215. sphinx/locale/si/LC_MESSAGES/sphinx.js +1 -1
  216. sphinx/locale/si/LC_MESSAGES/sphinx.mo +0 -0
  217. sphinx/locale/si/LC_MESSAGES/sphinx.po +700 -493
  218. sphinx/locale/sk/LC_MESSAGES/sphinx.js +1 -1
  219. sphinx/locale/sk/LC_MESSAGES/sphinx.mo +0 -0
  220. sphinx/locale/sk/LC_MESSAGES/sphinx.po +701 -494
  221. sphinx/locale/sl/LC_MESSAGES/sphinx.js +1 -1
  222. sphinx/locale/sl/LC_MESSAGES/sphinx.mo +0 -0
  223. sphinx/locale/sl/LC_MESSAGES/sphinx.po +701 -494
  224. sphinx/locale/sphinx.pot +702 -494
  225. sphinx/locale/sq/LC_MESSAGES/sphinx.js +1 -1
  226. sphinx/locale/sq/LC_MESSAGES/sphinx.mo +0 -0
  227. sphinx/locale/sq/LC_MESSAGES/sphinx.po +704 -497
  228. sphinx/locale/sr/LC_MESSAGES/sphinx.js +1 -1
  229. sphinx/locale/sr/LC_MESSAGES/sphinx.mo +0 -0
  230. sphinx/locale/sr/LC_MESSAGES/sphinx.po +700 -493
  231. sphinx/locale/sr@latin/LC_MESSAGES/sphinx.mo +0 -0
  232. sphinx/locale/sr_RS/LC_MESSAGES/sphinx.mo +0 -0
  233. sphinx/locale/sv/LC_MESSAGES/sphinx.js +1 -1
  234. sphinx/locale/sv/LC_MESSAGES/sphinx.mo +0 -0
  235. sphinx/locale/sv/LC_MESSAGES/sphinx.po +701 -494
  236. sphinx/locale/ta/LC_MESSAGES/sphinx.po +1016 -808
  237. sphinx/locale/te/LC_MESSAGES/sphinx.js +1 -1
  238. sphinx/locale/te/LC_MESSAGES/sphinx.mo +0 -0
  239. sphinx/locale/te/LC_MESSAGES/sphinx.po +700 -493
  240. sphinx/locale/tr/LC_MESSAGES/sphinx.js +1 -1
  241. sphinx/locale/tr/LC_MESSAGES/sphinx.mo +0 -0
  242. sphinx/locale/tr/LC_MESSAGES/sphinx.po +701 -494
  243. sphinx/locale/uk_UA/LC_MESSAGES/sphinx.js +1 -1
  244. sphinx/locale/uk_UA/LC_MESSAGES/sphinx.mo +0 -0
  245. sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po +701 -494
  246. sphinx/locale/ur/LC_MESSAGES/sphinx.js +1 -1
  247. sphinx/locale/ur/LC_MESSAGES/sphinx.mo +0 -0
  248. sphinx/locale/ur/LC_MESSAGES/sphinx.po +700 -493
  249. sphinx/locale/vi/LC_MESSAGES/sphinx.js +1 -1
  250. sphinx/locale/vi/LC_MESSAGES/sphinx.mo +0 -0
  251. sphinx/locale/vi/LC_MESSAGES/sphinx.po +701 -494
  252. sphinx/locale/yue/LC_MESSAGES/sphinx.js +1 -1
  253. sphinx/locale/yue/LC_MESSAGES/sphinx.mo +0 -0
  254. sphinx/locale/yue/LC_MESSAGES/sphinx.po +700 -493
  255. sphinx/locale/zh_CN/LC_MESSAGES/sphinx.po +704 -496
  256. sphinx/locale/zh_HK/LC_MESSAGES/sphinx.js +1 -1
  257. sphinx/locale/zh_HK/LC_MESSAGES/sphinx.mo +0 -0
  258. sphinx/locale/zh_HK/LC_MESSAGES/sphinx.po +700 -493
  259. sphinx/locale/zh_TW/LC_MESSAGES/sphinx.js +1 -1
  260. sphinx/locale/zh_TW/LC_MESSAGES/sphinx.mo +0 -0
  261. sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po +729 -522
  262. sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.js +1 -1
  263. sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.mo +0 -0
  264. sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.po +700 -493
  265. sphinx/roles.py +1 -1
  266. sphinx/search/__init__.py +17 -9
  267. sphinx/templates/quickstart/{root_doc.rst_t → root_doc.rst.jinja} +7 -10
  268. sphinx/testing/fixtures.py +22 -20
  269. sphinx/testing/path.py +6 -2
  270. sphinx/testing/util.py +8 -13
  271. sphinx/texinputs/sphinx.sty +449 -332
  272. sphinx/texinputs/sphinxlatexadmonitions.sty +209 -66
  273. sphinx/texinputs/sphinxlatexliterals.sty +9 -16
  274. sphinx/texinputs/sphinxlatexstyletext.sty +4 -38
  275. sphinx/texinputs/sphinxlatextables.sty +6 -14
  276. sphinx/texinputs/sphinxpackageboxes.sty +15 -42
  277. sphinx/texinputs/sphinxpackagefootnote.sty +4 -3
  278. sphinx/themes/agogo/layout.html +3 -3
  279. sphinx/themes/basic/genindex-single.html +2 -1
  280. sphinx/themes/basic/layout.html +3 -6
  281. sphinx/themes/basic/static/searchtools.js +4 -3
  282. sphinx/themes/haiku/layout.html +4 -4
  283. sphinx/themes/pyramid/layout.html +1 -1
  284. sphinx/themes/scrolls/layout.html +2 -2
  285. sphinx/theming.py +42 -7
  286. sphinx/transforms/__init__.py +34 -20
  287. sphinx/transforms/i18n.py +8 -7
  288. sphinx/transforms/post_transforms/__init__.py +1 -1
  289. sphinx/transforms/post_transforms/images.py +7 -10
  290. sphinx/util/_pathlib.py +2 -2
  291. sphinx/util/cfamily.py +52 -30
  292. sphinx/util/console.py +1 -1
  293. sphinx/util/display.py +16 -11
  294. sphinx/util/docutils.py +88 -40
  295. sphinx/util/fileutil.py +15 -3
  296. sphinx/util/images.py +1 -0
  297. sphinx/util/inspect.py +66 -22
  298. sphinx/util/inventory.py +15 -0
  299. sphinx/util/logging.py +14 -21
  300. sphinx/util/math.py +3 -1
  301. sphinx/util/nodes.py +9 -12
  302. sphinx/util/osutil.py +5 -5
  303. sphinx/util/parsing.py +93 -0
  304. sphinx/util/tags.py +71 -47
  305. sphinx/util/typing.py +261 -143
  306. sphinx/versioning.py +17 -17
  307. sphinx/writers/html5.py +26 -19
  308. sphinx/writers/latex.py +58 -28
  309. sphinx/writers/manpage.py +4 -3
  310. sphinx/writers/texinfo.py +19 -14
  311. {sphinx-7.3.6.dist-info → sphinx-7.4.0.dist-info}/METADATA +21 -20
  312. sphinx-7.4.0.dist-info/RECORD +591 -0
  313. sphinx-7.3.6.dist-info/RECORD +0 -581
  314. /sphinx/templates/apidoc/{module.rst_t → module.rst.jinja} +0 -0
  315. /sphinx/templates/apidoc/{package.rst_t → package.rst.jinja} +0 -0
  316. /sphinx/templates/apidoc/{toc.rst_t → toc.rst.jinja} +0 -0
  317. /sphinx/templates/epub3/{content.opf_t → content.opf.jinja} +0 -0
  318. /sphinx/templates/epub3/{nav.xhtml_t → nav.xhtml.jinja} +0 -0
  319. /sphinx/templates/epub3/{toc.ncx_t → toc.ncx.jinja} +0 -0
  320. /sphinx/templates/gettext/{message.pot_t → message.pot.jinja} +0 -0
  321. /sphinx/templates/imgmath/{preview.tex_t → preview.tex.jinja} +0 -0
  322. /sphinx/templates/imgmath/{template.tex_t → template.tex.jinja} +0 -0
  323. /sphinx/templates/latex/{latex.tex_t → latex.tex.jinja} +0 -0
  324. /sphinx/templates/latex/{longtable.tex_t → longtable.tex.jinja} +0 -0
  325. /sphinx/templates/latex/{sphinxmessages.sty_t → sphinxmessages.sty.jinja} +0 -0
  326. /sphinx/templates/latex/{tabular.tex_t → tabular.tex.jinja} +0 -0
  327. /sphinx/templates/latex/{tabulary.tex_t → tabulary.tex.jinja} +0 -0
  328. /sphinx/templates/quickstart/{Makefile_t → Makefile.jinja} +0 -0
  329. /sphinx/templates/quickstart/{Makefile.new_t → Makefile.new.jinja} +0 -0
  330. /sphinx/templates/quickstart/{conf.py_t → conf.py.jinja} +0 -0
  331. /sphinx/templates/quickstart/{make.bat_t → make.bat.jinja} +0 -0
  332. /sphinx/templates/quickstart/{make.bat.new_t → make.bat.new.jinja} +0 -0
  333. /sphinx/texinputs/{Makefile_t → Makefile.jinja} +0 -0
  334. /sphinx/texinputs/{latexmkjarc_t → latexmkjarc.jinja} +0 -0
  335. /sphinx/texinputs/{latexmkrc_t → latexmkrc.jinja} +0 -0
  336. /sphinx/texinputs/{make.bat_t → make.bat.jinja} +0 -0
  337. /sphinx/texinputs_win/{Makefile_t → Makefile.jinja} +0 -0
  338. /sphinx/themes/agogo/static/{agogo.css_t → agogo.css.jinja} +0 -0
  339. /sphinx/themes/basic/static/{basic.css_t → basic.css.jinja} +0 -0
  340. /sphinx/themes/basic/static/{documentation_options.js_t → documentation_options.js.jinja} +0 -0
  341. /sphinx/themes/basic/static/{language_data.js_t → language_data.js.jinja} +0 -0
  342. /sphinx/themes/bizstyle/static/{bizstyle.css_t → bizstyle.css.jinja} +0 -0
  343. /sphinx/themes/bizstyle/static/{bizstyle.js_t → bizstyle.js.jinja} +0 -0
  344. /sphinx/themes/classic/static/{classic.css_t → classic.css.jinja} +0 -0
  345. /sphinx/themes/classic/static/{sidebar.js_t → sidebar.js.jinja} +0 -0
  346. /sphinx/themes/epub/static/{epub.css_t → epub.css.jinja} +0 -0
  347. /sphinx/themes/haiku/static/{haiku.css_t → haiku.css.jinja} +0 -0
  348. /sphinx/themes/nature/static/{nature.css_t → nature.css.jinja} +0 -0
  349. /sphinx/themes/nonav/static/{nonav.css_t → nonav.css.jinja} +0 -0
  350. /sphinx/themes/pyramid/static/{epub.css_t → epub.css.jinja} +0 -0
  351. /sphinx/themes/pyramid/static/{pyramid.css_t → pyramid.css.jinja} +0 -0
  352. /sphinx/themes/scrolls/static/{scrolls.css_t → scrolls.css.jinja} +0 -0
  353. /sphinx/themes/sphinxdoc/static/{sphinxdoc.css_t → sphinxdoc.css.jinja} +0 -0
  354. /sphinx/themes/traditional/static/{traditional.css_t → traditional.css.jinja} +0 -0
  355. {sphinx-7.3.6.dist-info → sphinx-7.4.0.dist-info}/LICENSE.rst +0 -0
  356. {sphinx-7.3.6.dist-info → sphinx-7.4.0.dist-info}/WHEEL +0 -0
  357. {sphinx-7.3.6.dist-info → sphinx-7.4.0.dist-info}/entry_points.txt +0 -0
sphinx/config.py CHANGED
@@ -97,17 +97,19 @@ _OptValidTypes = Union[tuple[()], tuple[type, ...], frozenset[type], ENUM]
97
97
 
98
98
 
99
99
  class _Opt:
100
- __slots__ = 'default', 'rebuild', 'valid_types'
100
+ __slots__ = 'default', 'rebuild', 'valid_types', 'description'
101
101
 
102
102
  default: Any
103
103
  rebuild: _ConfigRebuild
104
104
  valid_types: _OptValidTypes
105
+ description: str
105
106
 
106
107
  def __init__(
107
108
  self,
108
109
  default: Any,
109
110
  rebuild: _ConfigRebuild,
110
111
  valid_types: _OptValidTypes,
112
+ description: str = '',
111
113
  ) -> None:
112
114
  """Configuration option type for Sphinx.
113
115
 
@@ -120,52 +122,56 @@ class _Opt:
120
122
  super().__setattr__('default', default)
121
123
  super().__setattr__('rebuild', rebuild)
122
124
  super().__setattr__('valid_types', valid_types)
125
+ super().__setattr__('description', description)
123
126
 
124
127
  def __repr__(self) -> str:
125
128
  return (
126
129
  f'{self.__class__.__qualname__}('
127
130
  f'default={self.default!r}, '
128
131
  f'rebuild={self.rebuild!r}, '
129
- f'valid_types={self.valid_types!r})'
132
+ f'valid_types={self.rebuild!r}, '
133
+ f'description={self.description!r})'
130
134
  )
131
135
 
132
136
  def __eq__(self, other: object) -> bool:
133
137
  if isinstance(other, _Opt):
134
- self_tpl = (self.default, self.rebuild, self.valid_types)
135
- other_tpl = (other.default, other.rebuild, other.valid_types)
138
+ self_tpl = (self.default, self.rebuild, self.valid_types, self.description)
139
+ other_tpl = (other.default, other.rebuild, other.valid_types, self.description)
136
140
  return self_tpl == other_tpl
137
141
  return NotImplemented
138
142
 
139
143
  def __lt__(self, other: _Opt) -> bool:
140
144
  if self.__class__ is other.__class__:
141
- self_tpl = (self.default, self.rebuild, self.valid_types)
142
- other_tpl = (other.default, other.rebuild, other.valid_types)
145
+ self_tpl = (self.default, self.rebuild, self.valid_types, self.description)
146
+ other_tpl = (other.default, other.rebuild, other.valid_types, self.description)
143
147
  return self_tpl > other_tpl
144
148
  return NotImplemented
145
149
 
146
150
  def __hash__(self) -> int:
147
- return hash((self.default, self.rebuild, self.valid_types))
151
+ return hash((self.default, self.rebuild, self.valid_types, self.description))
148
152
 
149
153
  def __setattr__(self, key: str, value: Any) -> None:
150
- if key in {'default', 'rebuild', 'valid_types'}:
154
+ if key in {'default', 'rebuild', 'valid_types', 'description'}:
151
155
  msg = f'{self.__class__.__name__!r} object does not support assignment to {key!r}'
152
156
  raise TypeError(msg)
153
157
  super().__setattr__(key, value)
154
158
 
155
159
  def __delattr__(self, key: str) -> None:
156
- if key in {'default', 'rebuild', 'valid_types'}:
160
+ if key in {'default', 'rebuild', 'valid_types', 'description'}:
157
161
  msg = f'{self.__class__.__name__!r} object does not support deletion of {key!r}'
158
162
  raise TypeError(msg)
159
163
  super().__delattr__(key)
160
164
 
161
- def __getstate__(self) -> tuple[Any, _ConfigRebuild, _OptValidTypes]:
162
- return self.default, self.rebuild, self.valid_types
165
+ def __getstate__(self) -> tuple[Any, _ConfigRebuild, _OptValidTypes, str]:
166
+ return self.default, self.rebuild, self.valid_types, self.description
163
167
 
164
- def __setstate__(self, state: tuple[Any, _ConfigRebuild, _OptValidTypes]) -> None:
165
- default, rebuild, valid_types = state
168
+ def __setstate__(
169
+ self, state: tuple[Any, _ConfigRebuild, _OptValidTypes, str]) -> None:
170
+ default, rebuild, valid_types, description = state
166
171
  super().__setattr__('default', default)
167
172
  super().__setattr__('rebuild', rebuild)
168
173
  super().__setattr__('valid_types', valid_types)
174
+ super().__setattr__('description', description)
169
175
 
170
176
  def __getitem__(self, item: int | slice) -> Any:
171
177
  warnings.warn(
@@ -196,11 +202,11 @@ class Config:
196
202
 
197
203
  config_values: dict[str, _Opt] = {
198
204
  # general options
199
- 'project': _Opt('Python', 'env', ()),
200
- 'author': _Opt('unknown', 'env', ()),
205
+ 'project': _Opt('Project name not set', 'env', ()),
206
+ 'author': _Opt('Author name not set', 'env', ()),
201
207
  'project_copyright': _Opt('', 'html', frozenset((str, tuple, list))),
202
208
  'copyright': _Opt(
203
- lambda c: c.project_copyright, 'html', frozenset((str, tuple, list))),
209
+ lambda config: config.project_copyright, 'html', frozenset((str, tuple, list))),
204
210
  'version': _Opt('', 'env', ()),
205
211
  'release': _Opt('', 'env', ()),
206
212
  'today': _Opt('', 'env', ()),
@@ -258,6 +264,7 @@ class Config:
258
264
  'math_number_all': _Opt(False, 'env', ()),
259
265
  'math_eqref_format': _Opt(None, 'env', frozenset((str,))),
260
266
  'math_numfig': _Opt(True, 'env', ()),
267
+ 'math_numsep': _Opt('.', 'env', frozenset((str,))),
261
268
  'tls_verify': _Opt(True, 'env', ()),
262
269
  'tls_cacerts': _Opt(None, 'env', ()),
263
270
  'user_agent': _Opt(None, 'env', frozenset((str,))),
@@ -326,34 +333,33 @@ class Config:
326
333
  valid_types = opt.valid_types
327
334
  if valid_types == Any:
328
335
  return value
329
- elif (type(default) is bool
330
- or (not isinstance(valid_types, ENUM)
331
- and len(valid_types) == 1 and bool in valid_types)):
336
+ if (type(default) is bool
337
+ or (not isinstance(valid_types, ENUM)
338
+ and len(valid_types) == 1 and bool in valid_types)):
332
339
  if isinstance(valid_types, ENUM) or len(valid_types) > 1:
333
340
  # if valid_types are given, and non-bool valid types exist,
334
341
  # return the value without coercing to a Boolean.
335
342
  return value
336
343
  # given falsy string from a command line option
337
344
  return value not in {'0', ''}
338
- elif isinstance(default, dict):
345
+ if isinstance(default, dict):
339
346
  raise ValueError(__('cannot override dictionary config setting %r, '
340
347
  'ignoring (use %r to set individual elements)') %
341
348
  (name, f'{name}.key=value'))
342
- elif isinstance(default, list):
349
+ if isinstance(default, list):
343
350
  return value.split(',')
344
- elif isinstance(default, int):
351
+ if isinstance(default, int):
345
352
  try:
346
353
  return int(value)
347
354
  except ValueError as exc:
348
355
  raise ValueError(__('invalid number %r for config value %r, ignoring') %
349
356
  (value, name)) from exc
350
- elif callable(default):
357
+ if callable(default):
351
358
  return value
352
- elif default is not None and not isinstance(default, str):
353
- raise ValueError(__('cannot override config setting %r with unsupported '
354
- 'type, ignoring') % name)
355
- else:
359
+ if isinstance(default, str) or default is None:
356
360
  return value
361
+ raise ValueError(__('cannot override config setting %r with unsupported '
362
+ 'type, ignoring') % name)
357
363
 
358
364
  @staticmethod
359
365
  def pre_init_values() -> None:
@@ -385,6 +391,18 @@ class Config:
385
391
  values.append(f"{opt_name}={opt_value!r}")
386
392
  return self.__class__.__qualname__ + '(' + ', '.join(values) + ')'
387
393
 
394
+ def __setattr__(self, key: str, value: object) -> None:
395
+ # Ensure aliases update their counterpart.
396
+ if key == 'master_doc':
397
+ super().__setattr__('root_doc', value)
398
+ elif key == 'root_doc':
399
+ super().__setattr__('master_doc', value)
400
+ elif key == 'copyright':
401
+ super().__setattr__('project_copyright', value)
402
+ elif key == 'project_copyright':
403
+ super().__setattr__('copyright', value)
404
+ super().__setattr__(key, value)
405
+
388
406
  def __getattr__(self, name: str) -> Any:
389
407
  if name in self._options:
390
408
  # first check command-line overrides
@@ -398,11 +416,12 @@ class Config:
398
416
  except ValueError as exc:
399
417
  logger.warning("%s", exc)
400
418
  else:
401
- self.__dict__[name] = value
419
+ self.__setattr__(name, value)
402
420
  return value
403
421
  # then check values from 'conf.py'
404
422
  if name in self._raw_config:
405
- self.__dict__[name] = value = self._raw_config[name]
423
+ value = self._raw_config[name]
424
+ self.__setattr__(name, value)
406
425
  return value
407
426
  # finally, fall back to the default value
408
427
  default = self._options[name].default
@@ -433,7 +452,8 @@ class Config:
433
452
  yield ConfigValue(name, getattr(self, name), opt.rebuild)
434
453
 
435
454
  def add(self, name: str, default: Any, rebuild: _ConfigRebuild,
436
- types: type | Collection[type] | ENUM) -> None:
455
+ types: type | Collection[type] | ENUM,
456
+ description: str = '') -> None:
437
457
  if name in self._options:
438
458
  raise ExtensionError(__('Config value %r already present') % name)
439
459
 
@@ -443,7 +463,7 @@ class Config:
443
463
 
444
464
  # standardise valid_types
445
465
  valid_types = _validate_valid_types(types)
446
- self._options[name] = _Opt(default, rebuild, valid_types)
466
+ self._options[name] = _Opt(default, rebuild, valid_types, description)
447
467
 
448
468
  def filter(self, rebuild: Set[_ConfigRebuild]) -> Iterator[ConfigValue]:
449
469
  if isinstance(rebuild, str):
@@ -561,10 +581,10 @@ def convert_source_suffix(app: Sphinx, config: Config) -> None:
561
581
  #
562
582
  # The default filetype is determined on later step.
563
583
  # By default, it is considered as restructuredtext.
564
- config.source_suffix = {source_suffix: None} # type: ignore[attr-defined]
584
+ config.source_suffix = {source_suffix: 'restructuredtext'}
565
585
  elif isinstance(source_suffix, (list, tuple)):
566
586
  # if list, considers as all of them are default filetype
567
- config.source_suffix = dict.fromkeys(source_suffix, None) # type: ignore[attr-defined]
587
+ config.source_suffix = dict.fromkeys(source_suffix, 'restructuredtext')
568
588
  elif not isinstance(source_suffix, dict):
569
589
  logger.warning(__("The config value `source_suffix' expects "
570
590
  "a string, list of strings, or dictionary. "
@@ -580,8 +600,7 @@ def convert_highlight_options(app: Sphinx, config: Config) -> None:
580
600
  options = config.highlight_options
581
601
  if options and not all(isinstance(v, dict) for v in options.values()):
582
602
  # old styled option detected because all values are not dictionary.
583
- config.highlight_options = {config.highlight_language: # type: ignore[attr-defined]
584
- options}
603
+ config.highlight_options = {config.highlight_language: options}
585
604
 
586
605
 
587
606
  def init_numfig_format(app: Sphinx, config: Config) -> None:
@@ -593,7 +612,7 @@ def init_numfig_format(app: Sphinx, config: Config) -> None:
593
612
 
594
613
  # override default labels by configuration
595
614
  numfig_format.update(config.numfig_format)
596
- config.numfig_format = numfig_format # type: ignore[attr-defined]
615
+ config.numfig_format = numfig_format
597
616
 
598
617
 
599
618
  def correct_copyright_year(_app: Sphinx, config: Config) -> None:
@@ -713,7 +732,7 @@ def check_primary_domain(app: Sphinx, config: Config) -> None:
713
732
  primary_domain = config.primary_domain
714
733
  if primary_domain and not app.registry.has_domain(primary_domain):
715
734
  logger.warning(__('primary_domain %r not found, ignored.'), primary_domain)
716
- config.primary_domain = None # type: ignore[attr-defined]
735
+ config.primary_domain = None
717
736
 
718
737
 
719
738
  def check_root_doc(app: Sphinx, env: BuildEnvironment, added: set[str],
@@ -726,7 +745,7 @@ def check_root_doc(app: Sphinx, env: BuildEnvironment, added: set[str],
726
745
  'contents' in app.project.docnames):
727
746
  logger.warning(__('Since v2.0, Sphinx uses "index" as root_doc by default. '
728
747
  'Please add "root_doc = \'contents\'" to your conf.py.'))
729
- app.config.root_doc = "contents" # type: ignore[attr-defined]
748
+ app.config.root_doc = "contents"
730
749
 
731
750
  return changed
732
751
 
@@ -13,7 +13,6 @@ from sphinx.addnodes import desc_signature # NoQA: TCH001
13
13
  from sphinx.util import docutils
14
14
  from sphinx.util.docfields import DocFieldTransformer, Field, TypedField
15
15
  from sphinx.util.docutils import SphinxDirective
16
- from sphinx.util.nodes import nested_parse_with_titles
17
16
  from sphinx.util.typing import ExtensionMetadata, OptionSpec # NoQA: TCH001
18
17
 
19
18
  if TYPE_CHECKING:
@@ -127,7 +126,7 @@ class ObjectDescription(SphinxDirective, Generic[ObjDescT]):
127
126
  """
128
127
  pass
129
128
 
130
- def transform_content(self, contentnode: addnodes.desc_content) -> None:
129
+ def transform_content(self, content_node: addnodes.desc_content) -> None:
131
130
  """
132
131
  Called after creating the content through nested parsing,
133
132
  but before the ``object-description-transform`` event is emitted,
@@ -275,18 +274,17 @@ class ObjectDescription(SphinxDirective, Generic[ObjDescT]):
275
274
  # description of the object with this name in this desc block
276
275
  self.add_target_and_index(name, sig, signode)
277
276
 
278
- contentnode = addnodes.desc_content()
279
- node.append(contentnode)
280
-
281
277
  if self.names:
282
278
  # needed for association of version{added,changed} directives
283
279
  self.env.temp_data['object'] = self.names[0]
284
280
  self.before_content()
285
- nested_parse_with_titles(self.state, self.content, contentnode, self.content_offset)
286
- self.transform_content(contentnode)
281
+ content_children = self.parse_content_to_nodes(allow_section_headings=True)
282
+ content_node = addnodes.desc_content('', *content_children)
283
+ node.append(content_node)
284
+ self.transform_content(content_node)
287
285
  self.env.app.emit('object-description-transform',
288
- self.domain, self.objtype, contentnode)
289
- DocFieldTransformer(self).transform_all(contentnode)
286
+ self.domain, self.objtype, content_node)
287
+ DocFieldTransformer(self).transform_all(content_node)
290
288
  self.env.temp_data['object'] = None
291
289
  self.after_content()
292
290
 
sphinx/directives/code.py CHANGED
@@ -7,7 +7,6 @@ from typing import TYPE_CHECKING, Any, ClassVar
7
7
 
8
8
  from docutils import nodes
9
9
  from docutils.parsers.rst import directives
10
- from docutils.statemachine import StringList
11
10
 
12
11
  from sphinx import addnodes
13
12
  from sphinx.directives import optional_int
@@ -75,15 +74,13 @@ def container_wrapper(
75
74
  ) -> nodes.container:
76
75
  container_node = nodes.container('', literal_block=True,
77
76
  classes=['literal-block-wrapper'])
78
- parsed = nodes.Element()
79
- directive.state.nested_parse(StringList([caption], source=''),
80
- directive.content_offset, parsed)
81
- if isinstance(parsed[0], nodes.system_message):
82
- msg = __('Invalid caption: %s' % parsed[0].astext())
77
+ parsed = directive.parse_text_to_nodes(caption, offset=directive.content_offset)
78
+ node = parsed[0]
79
+ if isinstance(node, nodes.system_message):
80
+ msg = __('Invalid caption: %s') % node.astext()
83
81
  raise ValueError(msg)
84
- if isinstance(parsed[0], nodes.Element):
85
- caption_node = nodes.caption(parsed[0].rawsource, '',
86
- *parsed[0].children)
82
+ if isinstance(node, nodes.Element):
83
+ caption_node = nodes.caption(node.rawsource, '', *node.children)
87
84
  caption_node.source = literal_node.source
88
85
  caption_node.line = literal_node.line
89
86
  container_node += caption_node
@@ -124,8 +121,8 @@ class CodeBlock(SphinxDirective):
124
121
  nlines = len(self.content)
125
122
  hl_lines = parselinenos(linespec, nlines)
126
123
  if any(i >= nlines for i in hl_lines):
127
- logger.warning(__('line number spec is out of range(1-%d): %r') %
128
- (nlines, self.options['emphasize-lines']),
124
+ logger.warning(__('line number spec is out of range(1-%d): %r'),
125
+ nlines, self.options['emphasize-lines'],
129
126
  location=location)
130
127
 
131
128
  hl_lines = [x + 1 for x in hl_lines if x < nlines]
@@ -274,8 +271,8 @@ class LiteralIncludeReader:
274
271
  if linespec:
275
272
  linelist = parselinenos(linespec, len(lines))
276
273
  if any(i >= len(lines) for i in linelist):
277
- logger.warning(__('line number spec is out of range(1-%d): %r') %
278
- (len(lines), linespec), location=location)
274
+ logger.warning(__('line number spec is out of range(1-%d): %r'),
275
+ len(lines), linespec, location=location)
279
276
 
280
277
  if 'lineno-match' in self.options:
281
278
  # make sure the line list is not "disjoint".
@@ -450,8 +447,8 @@ class LiteralInclude(SphinxDirective):
450
447
  if 'emphasize-lines' in self.options:
451
448
  hl_lines = parselinenos(self.options['emphasize-lines'], lines)
452
449
  if any(i >= lines for i in hl_lines):
453
- logger.warning(__('line number spec is out of range(1-%d): %r') %
454
- (lines, self.options['emphasize-lines']),
450
+ logger.warning(__('line number spec is out of range(1-%d): %r'),
451
+ lines, self.options['emphasize-lines'],
455
452
  location=location)
456
453
  extra_args['hl_lines'] = [x + 1 for x in hl_lines if x < lines]
457
454
  extra_args['linenostart'] = reader.lineno_start
@@ -53,6 +53,7 @@ class TocTree(SphinxDirective):
53
53
  option_spec = {
54
54
  'maxdepth': int,
55
55
  'name': directives.unchanged,
56
+ 'class': directives.class_option,
56
57
  'caption': directives.unchanged_required,
57
58
  'glob': directives.flag,
58
59
  'hidden': directives.flag,
@@ -78,7 +79,9 @@ class TocTree(SphinxDirective):
78
79
  subnode['numbered'] = self.options.get('numbered', 0)
79
80
  subnode['titlesonly'] = 'titlesonly' in self.options
80
81
  self.set_source_info(subnode)
81
- wrappernode = nodes.compound(classes=['toctree-wrapper'])
82
+ wrappernode = nodes.compound(
83
+ classes=['toctree-wrapper', *self.options.get('class', ())],
84
+ )
82
85
  wrappernode.append(subnode)
83
86
  self.add_name(wrappernode)
84
87
 
@@ -198,7 +201,7 @@ class Author(SphinxDirective):
198
201
  else:
199
202
  text = _('Author: ')
200
203
  emph += nodes.Text(text)
201
- inodes, messages = self.state.inline_text(self.arguments[0], self.lineno)
204
+ inodes, messages = self.parse_inline(self.arguments[0])
202
205
  emph.extend(inodes)
203
206
 
204
207
  ret: list[Node] = [para]
@@ -247,7 +250,7 @@ class Centered(SphinxDirective):
247
250
  if not self.arguments:
248
251
  return []
249
252
  subnode: Element = addnodes.centered()
250
- inodes, messages = self.state.inline_text(self.arguments[0], self.lineno)
253
+ inodes, messages = self.parse_inline(self.arguments[0])
251
254
  subnode.extend(inodes)
252
255
 
253
256
  ret: list[Node] = [subnode]
@@ -267,15 +270,12 @@ class Acks(SphinxDirective):
267
270
  option_spec: ClassVar[OptionSpec] = {}
268
271
 
269
272
  def run(self) -> list[Node]:
270
- node = addnodes.acks()
271
- node.document = self.state.document
272
- self.state.nested_parse(self.content, self.content_offset, node)
273
- if len(node.children) != 1 or not isinstance(node.children[0],
274
- nodes.bullet_list):
273
+ children = self.parse_content_to_nodes()
274
+ if len(children) != 1 or not isinstance(children[0], nodes.bullet_list):
275
275
  logger.warning(__('.. acks content is not a list'),
276
276
  location=(self.env.docname, self.lineno))
277
277
  return []
278
- return [node]
278
+ return [addnodes.acks('', *children)]
279
279
 
280
280
 
281
281
  class HList(SphinxDirective):
@@ -293,15 +293,12 @@ class HList(SphinxDirective):
293
293
 
294
294
  def run(self) -> list[Node]:
295
295
  ncolumns = self.options.get('columns', 2)
296
- node = nodes.paragraph()
297
- node.document = self.state.document
298
- self.state.nested_parse(self.content, self.content_offset, node)
299
- if len(node.children) != 1 or not isinstance(node.children[0],
300
- nodes.bullet_list):
296
+ children = self.parse_content_to_nodes()
297
+ if len(children) != 1 or not isinstance(children[0], nodes.bullet_list):
301
298
  logger.warning(__('.. hlist content is not a list'),
302
299
  location=(self.env.docname, self.lineno))
303
300
  return []
304
- fulllist = node.children[0]
301
+ fulllist = children[0]
305
302
  # create a hlist node where the items are distributed
306
303
  npercol, nmore = divmod(len(fulllist), ncolumns)
307
304
  index = 0
@@ -176,12 +176,38 @@ class MathDirective(SphinxDirective):
176
176
  ret.insert(0, target)
177
177
 
178
178
 
179
+ class Rubric(SphinxDirective):
180
+ """A patch of the docutils' :rst:dir:`rubric` directive,
181
+ which adds a level option to specify the heading level of the rubric.
182
+ """
183
+
184
+ required_arguments = 1
185
+ optional_arguments = 0
186
+ final_argument_whitespace = True
187
+ option_spec = {
188
+ 'class': directives.class_option,
189
+ 'name': directives.unchanged,
190
+ 'level': lambda c: directives.choice(c, ('1', '2', '3', '4', '5', '6')),
191
+ }
192
+
193
+ def run(self) -> list[Node]:
194
+ set_classes(self.options)
195
+ rubric_text = self.arguments[0]
196
+ textnodes, messages = self.parse_inline(rubric_text, lineno=self.lineno)
197
+ rubric = nodes.rubric(rubric_text, '', *textnodes, **self.options)
198
+ self.add_name(rubric)
199
+ if 'level' in self.options:
200
+ rubric['level'] = int(self.options['level'])
201
+ return [rubric, *messages]
202
+
203
+
179
204
  def setup(app: Sphinx) -> ExtensionMetadata:
180
205
  directives.register_directive('figure', Figure)
181
206
  directives.register_directive('meta', Meta)
182
207
  directives.register_directive('csv-table', CSVTable)
183
208
  directives.register_directive('code', Code)
184
209
  directives.register_directive('math', MathDirective)
210
+ directives.register_directive('rubric', Rubric)
185
211
 
186
212
  return {
187
213
  'version': 'builtin',
@@ -198,7 +198,7 @@ class Domain:
198
198
  #: data value for a fresh environment
199
199
  initial_data: dict = {}
200
200
  #: data value
201
- data: dict
201
+ data: dict[str, Any]
202
202
  #: data version, bump this when the format of `self.data` changes
203
203
  data_version = 0
204
204
 
@@ -543,7 +543,7 @@ class AliasTransform(SphinxTransform):
543
543
  signode.clear()
544
544
  signode += addnodes.desc_name(sig, sig)
545
545
 
546
- logger.warning("Could not find C declaration for alias '%s'." % name,
546
+ logger.warning("Could not find C declaration for alias '%s'.", name,
547
547
  location=node)
548
548
  node.replace_self(signode)
549
549
  continue
@@ -557,7 +557,7 @@ class AliasTransform(SphinxTransform):
557
557
  signode += addnodes.desc_name(sig, sig)
558
558
 
559
559
  logger.warning(
560
- "Can not render C declaration for alias '%s'. No such declaration." % name,
560
+ "Can not render C declaration for alias '%s'. No such declaration.", name,
561
561
  location=node)
562
562
  node.replace_self(signode)
563
563
  continue
@@ -835,9 +835,9 @@ class CDomain(Domain):
835
835
 
836
836
  def setup(app: Sphinx) -> ExtensionMetadata:
837
837
  app.add_domain(CDomain)
838
- app.add_config_value("c_id_attributes", [], 'env')
839
- app.add_config_value("c_paren_attributes", [], 'env')
840
- app.add_config_value("c_extra_keywords", _macroKeywords, 'env')
838
+ app.add_config_value("c_id_attributes", [], 'env', types={list, tuple})
839
+ app.add_config_value("c_paren_attributes", [], 'env', types={list, tuple})
840
+ app.add_config_value("c_extra_keywords", _macroKeywords, 'env', types={set, list})
841
841
  app.add_config_value("c_maximum_signature_line_length", None, 'env', types={int, None})
842
842
  app.add_post_transform(AliasTransform)
843
843