Sphinx 7.3.7__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 +44 -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 +3 -3
  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.7.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.7.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.7.dist-info → sphinx-7.4.0.dist-info}/LICENSE.rst +0 -0
  356. {sphinx-7.3.7.dist-info → sphinx-7.4.0.dist-info}/WHEEL +0 -0
  357. {sphinx-7.3.7.dist-info → sphinx-7.4.0.dist-info}/entry_points.txt +0 -0
@@ -5,7 +5,7 @@ from __future__ import annotations
5
5
  import re
6
6
  import unicodedata
7
7
  from itertools import groupby
8
- from typing import TYPE_CHECKING, Any, Literal
8
+ from typing import TYPE_CHECKING
9
9
 
10
10
  from sphinx.errors import NoUri
11
11
  from sphinx.locale import _, __
@@ -13,9 +13,42 @@ from sphinx.util import logging
13
13
  from sphinx.util.index_entries import _split_into
14
14
 
15
15
  if TYPE_CHECKING:
16
+ from typing import Literal, Optional, Union
17
+
18
+ from typing_extensions import TypeAlias
19
+
16
20
  from sphinx.builders import Builder
17
21
  from sphinx.environment import BuildEnvironment
18
22
 
23
+ _IndexEntryTarget: TypeAlias = tuple[Optional[str], Union[str, Literal[False]]]
24
+ _IndexEntryTargets: TypeAlias = list[_IndexEntryTarget]
25
+ _IndexEntryCategoryKey: TypeAlias = Optional[str]
26
+ _IndexEntrySubItems: TypeAlias = dict[
27
+ str,
28
+ tuple[_IndexEntryTargets, _IndexEntryCategoryKey],
29
+ ]
30
+ _IndexEntry: TypeAlias = tuple[
31
+ _IndexEntryTargets,
32
+ _IndexEntrySubItems,
33
+ _IndexEntryCategoryKey,
34
+ ]
35
+ _IndexEntryMap = dict[str, _IndexEntry]
36
+ _Index: TypeAlias = list[
37
+ tuple[
38
+ str,
39
+ list[
40
+ tuple[
41
+ str,
42
+ tuple[
43
+ _IndexEntryTargets,
44
+ list[tuple[str, _IndexEntryTargets]],
45
+ _IndexEntryCategoryKey
46
+ ]
47
+ ]
48
+ ]
49
+ ]
50
+ ]
51
+
19
52
  logger = logging.getLogger(__name__)
20
53
 
21
54
 
@@ -24,11 +57,14 @@ class IndexEntries:
24
57
  self.env = env
25
58
  self.builder: Builder
26
59
 
27
- def create_index(self, builder: Builder, group_entries: bool = True,
28
- _fixre: re.Pattern = re.compile(r'(.*) ([(][^()]*[)])'),
29
- ) -> list[tuple[str, list[tuple[str, Any]]]]:
60
+ def create_index(
61
+ self,
62
+ builder: Builder,
63
+ group_entries: bool = True,
64
+ _fixre: re.Pattern[str] = re.compile(r'(.*) ([(][^()]*[)])'),
65
+ ) -> _Index:
30
66
  """Create the real index from the collected index entries."""
31
- new: dict[str, list] = {}
67
+ new: _IndexEntryMap = {}
32
68
 
33
69
  rel_uri: str | Literal[False]
34
70
  index_domain = self.env.domains['index']
@@ -80,10 +116,10 @@ class IndexEntries:
80
116
 
81
117
  for (targets, sub_items, _category_key) in new.values():
82
118
  targets.sort(key=_key_func_0)
83
- for (sub_targets, _0, _sub_category_key) in sub_items.values():
119
+ for (sub_targets, _sub_category_key) in sub_items.values():
84
120
  sub_targets.sort(key=_key_func_0)
85
121
 
86
- new_list = sorted(new.items(), key=_key_func_1)
122
+ new_list: list[tuple[str, _IndexEntry]] = sorted(new.items(), key=_key_func_1)
87
123
 
88
124
  if group_entries:
89
125
  # fixup entries: transform
@@ -94,7 +130,7 @@ class IndexEntries:
94
130
  # (in module foo)
95
131
  # (in module bar)
96
132
  old_key = ''
97
- old_sub_items: dict[str, list] = {}
133
+ old_sub_items: _IndexEntrySubItems = {}
98
134
  i = 0
99
135
  while i < len(new_list):
100
136
  key, (targets, sub_items, category_key) = new_list[i]
@@ -106,7 +142,7 @@ class IndexEntries:
106
142
  # prefixes match: add entry as subitem of the
107
143
  # previous entry
108
144
  old_sub_items.setdefault(
109
- m.group(2), [[], {}, category_key])[0].extend(targets)
145
+ m.group(2), ([], category_key))[0].extend(targets)
110
146
  del new_list[i]
111
147
  continue
112
148
  old_key = m.group(1)
@@ -115,26 +151,41 @@ class IndexEntries:
115
151
  old_sub_items = sub_items
116
152
  i += 1
117
153
 
118
- return [(key_, list(group))
119
- for (key_, group) in groupby(new_list, _key_func_3)]
154
+ grouped = []
155
+ for (group_key, group) in groupby(new_list, _group_by_func):
156
+ group_list = []
157
+ for group_entry in group:
158
+ entry_key, (targets, sub_items, category_key) = group_entry
159
+ pairs = [
160
+ (sub_key, sub_targets)
161
+ for (sub_key, (sub_targets, _sub_category_key))
162
+ in sub_items.items()
163
+ ]
164
+ pairs.sort(key=_key_func_2)
165
+ group_list.append((entry_key, (targets, pairs, category_key)))
166
+ grouped.append((group_key, group_list))
167
+ return grouped
120
168
 
121
169
 
122
170
  def _add_entry(word: str, subword: str, main: str | None, *,
123
- dic: dict[str, list], link: str | Literal[False], key: str | None) -> None:
124
- entry = dic.setdefault(word, [[], {}, key])
171
+ dic: _IndexEntryMap,
172
+ link: str | Literal[False], key: _IndexEntryCategoryKey) -> None:
173
+ entry = dic.setdefault(word, ([], {}, key))
125
174
  if subword:
126
- entry = entry[1].setdefault(subword, [[], {}, key])
175
+ targets = entry[1].setdefault(subword, ([], key))[0]
176
+ else:
177
+ targets = entry[0]
127
178
  if link:
128
- entry[0].append((main, link))
179
+ targets.append((main, link))
129
180
 
130
181
 
131
- def _key_func_0(entry: tuple[str, str]) -> tuple[bool, str]:
182
+ def _key_func_0(entry: _IndexEntryTarget) -> tuple[bool, str | Literal[False]]:
132
183
  """Sort the index entries for same keyword."""
133
184
  main, uri = entry
134
185
  return not main, uri # show main entries at first
135
186
 
136
187
 
137
- def _key_func_1(entry: tuple[str, list]) -> tuple[tuple[int, str], str]:
188
+ def _key_func_1(entry: tuple[str, _IndexEntry]) -> tuple[tuple[int, str], str]:
138
189
  """Sort the index entries"""
139
190
  key, (_targets, _sub_items, category_key) = entry
140
191
  if category_key:
@@ -155,7 +206,7 @@ def _key_func_1(entry: tuple[str, list]) -> tuple[tuple[int, str], str]:
155
206
  return (group, lc_key), entry[0]
156
207
 
157
208
 
158
- def _key_func_2(entry: tuple[str, list]) -> str:
209
+ def _key_func_2(entry: tuple[str, _IndexEntryTargets]) -> str:
159
210
  """Sort the sub-index entries"""
160
211
  key = unicodedata.normalize('NFD', entry[0].lower())
161
212
  if key.startswith('\N{RIGHT-TO-LEFT MARK}'):
@@ -165,13 +216,9 @@ def _key_func_2(entry: tuple[str, list]) -> str:
165
216
  return key
166
217
 
167
218
 
168
- def _key_func_3(entry: tuple[str, list]) -> str:
169
- """Group the entries by letter"""
219
+ def _group_by_func(entry: tuple[str, _IndexEntry]) -> str:
220
+ """Group the entries by letter or category key."""
170
221
  key, (targets, sub_items, category_key) = entry
171
- # hack: mutating the sub_items dicts to a list in the key_func
172
- entry[1][1] = sorted(((sub_key, sub_targets)
173
- for (sub_key, (sub_targets, _0, _sub_category_key))
174
- in sub_items.items()), key=_key_func_2)
175
222
 
176
223
  if category_key is not None:
177
224
  return category_key
@@ -316,7 +316,7 @@ def _toctree_entry(
316
316
  # empty toc means: no titles will show up in the toctree
317
317
  logger.warning(__('toctree contains reference to document %r that '
318
318
  "doesn't have a title: no link will be generated"),
319
- ref, location=toctreenode)
319
+ ref, location=toctreenode, type='toc', subtype='no_title')
320
320
  except KeyError:
321
321
  # this is raised if the included file does not exist
322
322
  ref_path = env.doc2path(ref, False)
@@ -15,9 +15,13 @@ class EnvironmentCollector:
15
15
  """An EnvironmentCollector is a specific data collector from each document.
16
16
 
17
17
  It gathers data and stores :py:class:`BuildEnvironment
18
- <sphinx.environment.BuildEnvironment>` as a database. Examples of specific
19
- data would be images, download files, section titles, metadatas, index
18
+ <sphinx.environment.BuildEnvironment>` as a database.
19
+ Examples of specific data would be images, download files, section titles, metadatas, index
20
20
  entries and toctrees, etc.
21
+
22
+ .. note::
23
+
24
+ This class essentially wraps a sub-set of :ref:`Sphinx event callbacks <events>`.
21
25
  """
22
26
 
23
27
  listener_ids: dict[str, int] | None = None
@@ -42,6 +46,8 @@ class EnvironmentCollector:
42
46
  """Remove specified data of a document.
43
47
 
44
48
  This method is called on the removal of the document.
49
+
50
+ .. seealso:: :event:`env-purge-doc`
45
51
  """
46
52
  raise NotImplementedError
47
53
 
@@ -49,6 +55,8 @@ class EnvironmentCollector:
49
55
  docnames: set[str], other: BuildEnvironment) -> None:
50
56
  """Merge in specified data regarding docnames from a different `BuildEnvironment`
51
57
  object which coming from a subprocess in parallel builds.
58
+
59
+ .. seealso:: :event:`env-merge-info`
52
60
  """
53
61
  raise NotImplementedError
54
62
 
@@ -56,13 +64,17 @@ class EnvironmentCollector:
56
64
  """Process a document and gather specific data from it.
57
65
 
58
66
  This method is called after the document is read.
67
+
68
+ .. seealso:: :event:`doctree-read`
59
69
  """
60
70
  raise NotImplementedError
61
71
 
62
72
  def get_updated_docs(self, app: Sphinx, env: BuildEnvironment) -> list[str]:
63
73
  """Return a list of docnames to re-read.
64
74
 
65
- This methods is called after reading the whole of documents (experimental).
75
+ This method is called after reading the whole of documents.
76
+
77
+ .. seealso:: :event:`env-get-updated`
66
78
  """
67
79
  return []
68
80
 
@@ -70,6 +82,8 @@ class EnvironmentCollector:
70
82
  added: set[str], changed: set[str], removed: set[str]) -> list[str]:
71
83
  """Return a list of docnames to re-read.
72
84
 
73
- This methods is called before reading the documents.
85
+ This method is called before reading the documents.
86
+
87
+ .. seealso:: :event:`env-get-outdated`
74
88
  """
75
89
  return []
@@ -86,7 +86,7 @@ class ImageCollector(EnvironmentCollector):
86
86
  for imgpath in candidates.values():
87
87
  app.env.dependencies[docname].add(imgpath)
88
88
  if not os.access(path.join(app.srcdir, imgpath), os.R_OK):
89
- logger.warning(__('image file not readable: %s') % imgpath,
89
+ logger.warning(__('image file not readable: %s'), imgpath,
90
90
  location=node, type='image', subtype='not_readable')
91
91
  continue
92
92
  app.env.images.add_file(docname, imgpath)
@@ -105,10 +105,10 @@ class ImageCollector(EnvironmentCollector):
105
105
  if mimetype not in candidates:
106
106
  globbed.setdefault(mimetype, []).append(new_imgpath)
107
107
  except OSError as err:
108
- logger.warning(__('image file %s not readable: %s') % (filename, err),
108
+ logger.warning(__('image file %s not readable: %s'), filename, err,
109
109
  location=node, type='image', subtype='not_readable')
110
110
  for key, files in globbed.items():
111
- candidates[key] = sorted(files, key=len)[0] # select by similarity
111
+ candidates[key] = min(files, key=len) # select by similarity
112
112
 
113
113
 
114
114
  class DownloadFileCollector(EnvironmentCollector):
@@ -131,7 +131,7 @@ class DownloadFileCollector(EnvironmentCollector):
131
131
  rel_filename, filename = app.env.relfn2path(targetname, app.env.docname)
132
132
  app.env.dependencies[app.env.docname].add(rel_filename)
133
133
  if not os.access(filename, os.R_OK):
134
- logger.warning(__('download file not readable: %s') % filename,
134
+ logger.warning(__('download file not readable: %s'), filename,
135
135
  location=node, type='download', subtype='not_readable')
136
136
  continue
137
137
  node['filename'] = app.env.dlfiles.add_file(app.env.docname, rel_filename)
@@ -68,8 +68,6 @@ class TocTreeCollector(EnvironmentCollector):
68
68
  ) -> nodes.bullet_list | None:
69
69
  # list of table of contents entries
70
70
  entries: list[Element] = []
71
- # cache of parents -> list item
72
- memo_parents: dict[tuple[str, ...], nodes.list_item] = {}
73
71
  for sectionnode in node:
74
72
  # find all toctree nodes in this section and add them
75
73
  # to the toc (just copying the toctree node which is then
@@ -103,6 +101,8 @@ class TocTreeCollector(EnvironmentCollector):
103
101
  entries.append(onlynode)
104
102
  # check within the section for other node types
105
103
  elif isinstance(sectionnode, nodes.Element):
104
+ # cache of parent node -> list item
105
+ memo_parents: dict[nodes.Element, nodes.list_item] = {}
106
106
  toctreenode: nodes.Node
107
107
  for toctreenode in sectionnode.findall():
108
108
  if isinstance(toctreenode, nodes.section):
@@ -114,6 +114,10 @@ class TocTreeCollector(EnvironmentCollector):
114
114
  note_toctree(app.env, docname, toctreenode)
115
115
  # add object signatures within a section to the ToC
116
116
  elif isinstance(toctreenode, addnodes.desc):
117
+ # The desc has one or more nested desc_signature,
118
+ # and then a desc_content, which again may have desc nodes.
119
+ # Thus, desc is the one we can bubble up to through parents.
120
+ entry: nodes.list_item | None = None
117
121
  for sig_node in toctreenode:
118
122
  if not isinstance(sig_node, addnodes.desc_signature):
119
123
  continue
@@ -136,22 +140,28 @@ class TocTreeCollector(EnvironmentCollector):
136
140
  para = addnodes.compact_paragraph('', '', reference,
137
141
  skip_section_number=True)
138
142
  entry = nodes.list_item('', para)
139
- *parents, _ = sig_node['_toc_parts']
140
- parents = tuple(parents)
141
143
 
142
- # Cache parents tuple
143
- memo_parents[sig_node['_toc_parts']] = entry
144
-
145
- # Nest children within parents
146
- if parents and parents in memo_parents:
147
- root_entry = memo_parents[parents]
144
+ # Find parent node
145
+ parent = sig_node.parent
146
+ while parent not in memo_parents and parent != sectionnode:
147
+ parent = parent.parent
148
+ # Note, it may both be the limit and in memo_parents,
149
+ # prefer memo_parents, so we get the nesting.
150
+ if parent in memo_parents:
151
+ root_entry = memo_parents[parent]
148
152
  if isinstance(root_entry[-1], nodes.bullet_list):
149
153
  root_entry[-1].append(entry)
150
154
  else:
151
155
  root_entry.append(nodes.bullet_list('', entry))
152
- continue
156
+ else:
157
+ assert parent == sectionnode
158
+ entries.append(entry)
153
159
 
154
- entries.append(entry)
160
+ # Save the latest desc_signature as the one we put sub entries in.
161
+ # If there are multiple signatures, then the latest is used.
162
+ if entry is not None:
163
+ # are there any desc nodes without desc_signature nodes?
164
+ memo_parents[toctreenode] = entry
155
165
 
156
166
  if entries:
157
167
  return nodes.bullet_list('', *entries)
@@ -177,7 +187,10 @@ class TocTreeCollector(EnvironmentCollector):
177
187
  env.toc_secnumbers = {}
178
188
 
179
189
  def _walk_toc(
180
- node: Element, secnums: dict, depth: int, titlenode: nodes.title | None = None,
190
+ node: Element,
191
+ secnums: dict[str, tuple[int, ...]],
192
+ depth: int,
193
+ titlenode: nodes.title | None = None,
181
194
  ) -> None:
182
195
  # titlenode is the title of the document, it will get assigned a
183
196
  # secnumber too, so that it shows up in next/prev/parent rellinks
@@ -206,7 +219,7 @@ class TocTreeCollector(EnvironmentCollector):
206
219
  secnums[reference['anchorname']] = tuple(numstack)
207
220
  else:
208
221
  number = None
209
- secnums[reference['anchorname']] = None
222
+ secnums[reference['anchorname']] = ()
210
223
  reference['secnumber'] = number
211
224
  if titlenode:
212
225
  titlenode['secnumber'] = number
sphinx/events.py CHANGED
@@ -30,21 +30,22 @@ class EventListener(NamedTuple):
30
30
 
31
31
  # List of all known core events. Maps name to arguments description.
32
32
  core_events = {
33
- 'builder-inited': '',
34
33
  'config-inited': 'config',
34
+ 'builder-inited': '',
35
35
  'env-get-outdated': 'env, added, changed, removed',
36
- 'env-get-updated': 'env',
37
- 'env-purge-doc': 'env, docname',
38
36
  'env-before-read-docs': 'env, docnames',
39
- 'env-check-consistency': 'env',
37
+ 'env-purge-doc': 'env, docname',
40
38
  'source-read': 'docname, source text',
41
39
  'include-read': 'relative path, parent docname, source text',
42
40
  'doctree-read': 'the doctree before being pickled',
43
41
  'env-merge-info': 'env, read docnames, other env instance',
42
+ 'env-updated': 'env',
43
+ 'env-get-updated': 'env',
44
+ 'env-check-consistency': 'env',
45
+ 'write-started': 'builder',
46
+ 'doctree-resolved': 'doctree, docname',
44
47
  'missing-reference': 'env, node, contnode',
45
48
  'warn-missing-reference': 'domain, node',
46
- 'doctree-resolved': 'doctree, docname',
47
- 'env-updated': 'env',
48
49
  'build-finished': 'exception',
49
50
  }
50
51