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
@@ -1,295 +1,34 @@
1
- """Insert links to objects documented in remote Sphinx documentation.
2
-
3
- This works as follows:
4
-
5
- * Each Sphinx HTML build creates a file named "objects.inv" that contains a
6
- mapping from object names to URIs relative to the HTML set's root.
7
-
8
- * Projects using the Intersphinx extension can specify links to such mapping
9
- files in the `intersphinx_mapping` config value. The mapping will then be
10
- used to resolve otherwise missing references to objects into links to the
11
- other documentation.
12
-
13
- * By default, the mapping file is assumed to be at the same location as the
14
- rest of the documentation; however, the location of the mapping file can
15
- also be specified individually, e.g. if the docs should be buildable
16
- without Internet access.
17
- """
1
+ """This module provides logic for resolving references to intersphinx targets."""
18
2
 
19
3
  from __future__ import annotations
20
4
 
21
- import concurrent.futures
22
- import functools
23
5
  import posixpath
24
6
  import re
25
- import sys
26
- import time
27
- from os import path
28
7
  from typing import TYPE_CHECKING, cast
29
- from urllib.parse import urlsplit, urlunsplit
30
8
 
31
9
  from docutils import nodes
32
10
  from docutils.utils import relative_path
33
11
 
34
- import sphinx
35
12
  from sphinx.addnodes import pending_xref
36
- from sphinx.builders.html import INVENTORY_FILENAME
37
13
  from sphinx.deprecation import _deprecation_warning
38
14
  from sphinx.errors import ExtensionError
15
+ from sphinx.ext.intersphinx._shared import LOGGER, InventoryAdapter
39
16
  from sphinx.locale import _, __
40
17
  from sphinx.transforms.post_transforms import ReferencesResolver
41
- from sphinx.util import logging, requests
42
18
  from sphinx.util.docutils import CustomReSTDispatcher, SphinxRole
43
- from sphinx.util.inventory import InventoryFile
44
19
 
45
20
  if TYPE_CHECKING:
46
21
  from collections.abc import Iterable
47
22
  from types import ModuleType
48
- from typing import IO, Any, Union
23
+ from typing import Any
49
24
 
50
25
  from docutils.nodes import Node, TextElement, system_message
51
26
  from docutils.utils import Reporter
52
27
 
53
28
  from sphinx.application import Sphinx
54
- from sphinx.config import Config
55
29
  from sphinx.domains import Domain
56
30
  from sphinx.environment import BuildEnvironment
57
- from sphinx.util.typing import ExtensionMetadata, Inventory, InventoryItem, RoleFunction
58
-
59
- InventoryCacheEntry = tuple[Union[str, None], int, Inventory]
60
-
61
- logger = logging.getLogger(__name__)
62
-
63
-
64
- class InventoryAdapter:
65
- """Inventory adapter for environment"""
66
-
67
- def __init__(self, env: BuildEnvironment) -> None:
68
- self.env = env
69
-
70
- if not hasattr(env, 'intersphinx_cache'):
71
- # initial storage when fetching inventories before processing
72
- self.env.intersphinx_cache = {} # type: ignore[attr-defined]
73
-
74
- self.env.intersphinx_inventory = {} # type: ignore[attr-defined]
75
- self.env.intersphinx_named_inventory = {} # type: ignore[attr-defined]
76
-
77
- @property
78
- def cache(self) -> dict[str, InventoryCacheEntry]:
79
- """Intersphinx cache.
80
-
81
- - Key is the URI of the remote inventory
82
- - Element one is the key given in the Sphinx intersphinx_mapping
83
- configuration value
84
- - Element two is a time value for cache invalidation, a float
85
- - Element three is the loaded remote inventory, type Inventory
86
- """
87
- return self.env.intersphinx_cache # type: ignore[attr-defined]
88
-
89
- @property
90
- def main_inventory(self) -> Inventory:
91
- return self.env.intersphinx_inventory # type: ignore[attr-defined]
92
-
93
- @property
94
- def named_inventory(self) -> dict[str, Inventory]:
95
- return self.env.intersphinx_named_inventory # type: ignore[attr-defined]
96
-
97
- def clear(self) -> None:
98
- self.env.intersphinx_inventory.clear() # type: ignore[attr-defined]
99
- self.env.intersphinx_named_inventory.clear() # type: ignore[attr-defined]
100
-
101
-
102
- def _strip_basic_auth(url: str) -> str:
103
- """Returns *url* with basic auth credentials removed. Also returns the
104
- basic auth username and password if they're present in *url*.
105
-
106
- E.g.: https://user:pass@example.com => https://example.com
107
-
108
- *url* need not include basic auth credentials.
109
-
110
- :param url: url which may or may not contain basic auth credentials
111
- :type url: ``str``
112
-
113
- :return: *url* with any basic auth creds removed
114
- :rtype: ``str``
115
- """
116
- frags = list(urlsplit(url))
117
- # swap out "user[:pass]@hostname" for "hostname"
118
- if '@' in frags[1]:
119
- frags[1] = frags[1].split('@')[1]
120
- return urlunsplit(frags)
121
-
122
-
123
- def _read_from_url(url: str, *, config: Config) -> IO:
124
- """Reads data from *url* with an HTTP *GET*.
125
-
126
- This function supports fetching from resources which use basic HTTP auth as
127
- laid out by RFC1738 § 3.1. See § 5 for grammar definitions for URLs.
128
-
129
- .. seealso:
130
-
131
- https://www.ietf.org/rfc/rfc1738.txt
132
-
133
- :param url: URL of an HTTP resource
134
- :type url: ``str``
135
-
136
- :return: data read from resource described by *url*
137
- :rtype: ``file``-like object
138
- """
139
- r = requests.get(url, stream=True, timeout=config.intersphinx_timeout,
140
- _user_agent=config.user_agent,
141
- _tls_info=(config.tls_verify, config.tls_cacerts))
142
- r.raise_for_status()
143
- r.raw.url = r.url
144
- # decode content-body based on the header.
145
- # ref: https://github.com/psf/requests/issues/2155
146
- r.raw.read = functools.partial(r.raw.read, decode_content=True)
147
- return r.raw
148
-
149
-
150
- def _get_safe_url(url: str) -> str:
151
- """Gets version of *url* with basic auth passwords obscured. This function
152
- returns results suitable for printing and logging.
153
-
154
- E.g.: https://user:12345@example.com => https://user@example.com
155
-
156
- :param url: a url
157
- :type url: ``str``
158
-
159
- :return: *url* with password removed
160
- :rtype: ``str``
161
- """
162
- parts = urlsplit(url)
163
- if parts.username is None:
164
- return url
165
- else:
166
- frags = list(parts)
167
- if parts.port:
168
- frags[1] = f'{parts.username}@{parts.hostname}:{parts.port}'
169
- else:
170
- frags[1] = f'{parts.username}@{parts.hostname}'
171
-
172
- return urlunsplit(frags)
173
-
174
-
175
- def fetch_inventory(app: Sphinx, uri: str, inv: str) -> Inventory:
176
- """Fetch, parse and return an intersphinx inventory file."""
177
- # both *uri* (base URI of the links to generate) and *inv* (actual
178
- # location of the inventory file) can be local or remote URIs
179
- if '://' in uri:
180
- # case: inv URI points to remote resource; strip any existing auth
181
- uri = _strip_basic_auth(uri)
182
- try:
183
- if '://' in inv:
184
- f = _read_from_url(inv, config=app.config)
185
- else:
186
- f = open(path.join(app.srcdir, inv), 'rb') # NoQA: SIM115
187
- except Exception as err:
188
- err.args = ('intersphinx inventory %r not fetchable due to %s: %s',
189
- inv, err.__class__, str(err))
190
- raise
191
- try:
192
- if hasattr(f, 'url'):
193
- newinv = f.url
194
- if inv != newinv:
195
- logger.info(__('intersphinx inventory has moved: %s -> %s'), inv, newinv)
196
-
197
- if uri in (inv, path.dirname(inv), path.dirname(inv) + '/'):
198
- uri = path.dirname(newinv)
199
- with f:
200
- try:
201
- invdata = InventoryFile.load(f, uri, posixpath.join)
202
- except ValueError as exc:
203
- raise ValueError('unknown or unsupported inventory version: %r' % exc) from exc
204
- except Exception as err:
205
- err.args = ('intersphinx inventory %r not readable due to %s: %s',
206
- inv, err.__class__.__name__, str(err))
207
- raise
208
- else:
209
- return invdata
210
-
211
-
212
- def fetch_inventory_group(
213
- name: str | None,
214
- uri: str,
215
- invs: tuple[str | None, ...],
216
- cache: dict[str, InventoryCacheEntry],
217
- app: Sphinx,
218
- now: int,
219
- ) -> bool:
220
- cache_time = now - app.config.intersphinx_cache_limit * 86400
221
- failures = []
222
- try:
223
- for inv in invs:
224
- if not inv:
225
- inv = posixpath.join(uri, INVENTORY_FILENAME)
226
- # decide whether the inventory must be read: always read local
227
- # files; remote ones only if the cache time is expired
228
- if '://' not in inv or uri not in cache or cache[uri][1] < cache_time:
229
- safe_inv_url = _get_safe_url(inv)
230
- logger.info(__('loading intersphinx inventory from %s...'), safe_inv_url)
231
- try:
232
- invdata = fetch_inventory(app, uri, inv)
233
- except Exception as err:
234
- failures.append(err.args)
235
- continue
236
- if invdata:
237
- cache[uri] = name, now, invdata
238
- return True
239
- return False
240
- finally:
241
- if failures == []:
242
- pass
243
- elif len(failures) < len(invs):
244
- logger.info(__("encountered some issues with some of the inventories,"
245
- " but they had working alternatives:"))
246
- for fail in failures:
247
- logger.info(*fail)
248
- else:
249
- issues = '\n'.join(f[0] % f[1:] for f in failures)
250
- logger.warning(__("failed to reach any of the inventories "
251
- "with the following issues:") + "\n" + issues)
252
-
253
-
254
- def load_mappings(app: Sphinx) -> None:
255
- """Load all intersphinx mappings into the environment."""
256
- now = int(time.time())
257
- inventories = InventoryAdapter(app.builder.env)
258
- intersphinx_cache: dict[str, InventoryCacheEntry] = inventories.cache
259
-
260
- with concurrent.futures.ThreadPoolExecutor() as pool:
261
- futures = []
262
- name: str | None
263
- uri: str
264
- invs: tuple[str | None, ...]
265
- for name, (uri, invs) in app.config.intersphinx_mapping.values():
266
- futures.append(pool.submit(
267
- fetch_inventory_group, name, uri, invs, intersphinx_cache, app, now,
268
- ))
269
- updated = [f.result() for f in concurrent.futures.as_completed(futures)]
270
-
271
- if any(updated):
272
- inventories.clear()
273
-
274
- # Duplicate values in different inventories will shadow each
275
- # other; which one will override which can vary between builds
276
- # since they are specified using an unordered dict. To make
277
- # it more consistent, we sort the named inventories and then
278
- # add the unnamed inventories last. This means that the
279
- # unnamed inventories will shadow the named ones but the named
280
- # ones can still be accessed when the name is specified.
281
- named_vals = []
282
- unnamed_vals = []
283
- for name, _expiry, invdata in intersphinx_cache.values():
284
- if name:
285
- named_vals.append((name, invdata))
286
- else:
287
- unnamed_vals.append((name, invdata))
288
- for name, invdata in sorted(named_vals) + unnamed_vals:
289
- if name:
290
- inventories.named_inventory[name] = invdata
291
- for type, objects in invdata.items():
292
- inventories.main_inventory.setdefault(type, {}).update(objects)
31
+ from sphinx.util.typing import Inventory, InventoryItem, RoleFunction
293
32
 
294
33
 
295
34
  def _create_element_from_result(domain: Domain, inv_name: str | None,
@@ -307,8 +46,7 @@ def _create_element_from_result(domain: Domain, inv_name: str | None,
307
46
  if node.get('refexplicit'):
308
47
  # use whatever title was given
309
48
  newnode.append(contnode)
310
- elif dispname == '-' or \
311
- (domain.name == 'std' and node['reftype'] == 'keyword'):
49
+ elif dispname == '-' or (domain.name == 'std' and node['reftype'] == 'keyword'):
312
50
  # use whatever title was given, but strip prefix
313
51
  title = contnode.astext()
314
52
  if inv_name is not None and title.startswith(inv_name + ':'):
@@ -342,6 +80,11 @@ def _resolve_reference_in_domain_by_target(
342
80
  target_lower = target.lower()
343
81
  insensitive_matches = list(filter(lambda k: k.lower() == target_lower,
344
82
  inventory[objtype].keys()))
83
+ if len(insensitive_matches) > 1:
84
+ inv_descriptor = inv_name or 'main_inventory'
85
+ LOGGER.warning(__("inventory '%s': multiple matches found for %s:%s"),
86
+ inv_descriptor, objtype, target,
87
+ type='intersphinx', subtype='external', location=node)
345
88
  if insensitive_matches:
346
89
  data = inventory[objtype][insensitive_matches[0]]
347
90
  else:
@@ -374,7 +117,7 @@ def _resolve_reference_in_domain(env: BuildEnvironment,
374
117
 
375
118
  # the inventory contains domain:type as objtype
376
119
  domain_name = domain.name
377
- obj_types = {f"{domain_name}:{obj_type}": None for obj_type in obj_types}
120
+ obj_types = {f'{domain_name}:{obj_type}': None for obj_type in obj_types}
378
121
 
379
122
  # now that the objtypes list is complete we can remove the disabled ones
380
123
  if honor_disabled_refs:
@@ -412,7 +155,7 @@ def _resolve_reference(env: BuildEnvironment, inv_name: str | None, inventory: I
412
155
  if typ == 'any':
413
156
  for domain_name, domain in env.domains.items():
414
157
  if (honor_disabled_refs
415
- and (domain_name + ":*") in env.config.intersphinx_disabled_reftypes):
158
+ and (domain_name + ':*') in env.config.intersphinx_disabled_reftypes):
416
159
  continue
417
160
  objtypes: Iterable[str] = domain.object_types.keys()
418
161
  res = _resolve_reference_in_domain(env, inv_name, inventory,
@@ -427,8 +170,8 @@ def _resolve_reference(env: BuildEnvironment, inv_name: str | None, inventory: I
427
170
  if not domain_name:
428
171
  # only objects in domains are in the inventory
429
172
  return None
430
- if honor_disabled_refs \
431
- and (domain_name + ":*") in env.config.intersphinx_disabled_reftypes:
173
+ if (honor_disabled_refs
174
+ and (domain_name + ':*') in env.config.intersphinx_disabled_reftypes):
432
175
  return None
433
176
  domain = env.get_domain(domain_name)
434
177
  objtypes = domain.objtypes_for_role(typ) or ()
@@ -525,7 +268,7 @@ class IntersphinxRole(SphinxRole):
525
268
  # group 1: just for the optionality of the inventory name
526
269
  # group 2: the inventory name (optional)
527
270
  # group 3: the domain:role or role part
528
- _re_inv_ref = re.compile(r"(\+([^:]+))?:(.*)")
271
+ _re_inv_ref = re.compile(r'(\+([^:]+))?:(.*)')
529
272
 
530
273
  def __init__(self, orig_name: str) -> None:
531
274
  self.orig_name = orig_name
@@ -663,7 +406,7 @@ class IntersphinxRole(SphinxRole):
663
406
  return None, None
664
407
 
665
408
  def _emit_warning(self, msg: str, /, *args: Any) -> None:
666
- logger.warning(
409
+ LOGGER.warning(
667
410
  msg,
668
411
  *args,
669
412
  type='intersphinx',
@@ -749,7 +492,7 @@ class IntersphinxRoleResolver(ReferencesResolver):
749
492
  typ = node['reftype']
750
493
  msg = (__('external %s:%s reference target not found: %s') %
751
494
  (node['refdomain'], typ, node['reftarget']))
752
- logger.warning(msg, location=node, type='ref', subtype=typ)
495
+ LOGGER.warning(msg, location=node, type='ref', subtype=typ)
753
496
  node.replace_self(contnode)
754
497
  else:
755
498
  node.replace_self(newnode)
@@ -763,97 +506,3 @@ def install_dispatcher(app: Sphinx, docname: str, source: list[str]) -> None:
763
506
  """
764
507
  dispatcher = IntersphinxDispatcher()
765
508
  dispatcher.enable()
766
-
767
-
768
- def normalize_intersphinx_mapping(app: Sphinx, config: Config) -> None:
769
- for key, value in config.intersphinx_mapping.copy().items():
770
- try:
771
- if isinstance(value, (list, tuple)):
772
- # new format
773
- name, (uri, inv) = key, value
774
- if not isinstance(name, str):
775
- logger.warning(__('intersphinx identifier %r is not string. Ignored'),
776
- name)
777
- config.intersphinx_mapping.pop(key)
778
- continue
779
- else:
780
- # old format, no name
781
- # xref RemovedInSphinx80Warning
782
- name, uri, inv = None, key, value
783
- msg = (
784
- "The pre-Sphinx 1.0 'intersphinx_mapping' format is "
785
- "deprecated and will be removed in Sphinx 8. Update to the "
786
- "current format as described in the documentation. "
787
- f"Hint: \"intersphinx_mapping = {{'<name>': {(uri, inv)!r}}}\"."
788
- "https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html#confval-intersphinx_mapping" # NoQA: E501
789
- )
790
- logger.warning(msg)
791
-
792
- if not isinstance(inv, tuple):
793
- config.intersphinx_mapping[key] = (name, (uri, (inv,)))
794
- else:
795
- config.intersphinx_mapping[key] = (name, (uri, inv))
796
- except Exception as exc:
797
- logger.warning(__('Failed to read intersphinx_mapping[%s], ignored: %r'), key, exc)
798
- config.intersphinx_mapping.pop(key)
799
-
800
-
801
- def setup(app: Sphinx) -> ExtensionMetadata:
802
- app.add_config_value('intersphinx_mapping', {}, 'env')
803
- app.add_config_value('intersphinx_cache_limit', 5, '')
804
- app.add_config_value('intersphinx_timeout', None, '')
805
- app.add_config_value('intersphinx_disabled_reftypes', ['std:doc'], 'env')
806
- app.connect('config-inited', normalize_intersphinx_mapping, priority=800)
807
- app.connect('builder-inited', load_mappings)
808
- app.connect('source-read', install_dispatcher)
809
- app.connect('missing-reference', missing_reference)
810
- app.add_post_transform(IntersphinxRoleResolver)
811
- return {
812
- 'version': sphinx.__display_version__,
813
- 'env_version': 1,
814
- 'parallel_read_safe': True,
815
- }
816
-
817
-
818
- def inspect_main(argv: list[str], /) -> int:
819
- """Debug functionality to print out an inventory"""
820
- if len(argv) < 1:
821
- print("Print out an inventory file.\n"
822
- "Error: must specify local path or URL to an inventory file.",
823
- file=sys.stderr)
824
- return 1
825
-
826
- class MockConfig:
827
- intersphinx_timeout: int | None = None
828
- tls_verify = False
829
- tls_cacerts: str | dict[str, str] | None = None
830
- user_agent: str = ''
831
-
832
- class MockApp:
833
- srcdir = ''
834
- config = MockConfig()
835
-
836
- try:
837
- filename = argv[0]
838
- inv_data = fetch_inventory(MockApp(), '', filename) # type: ignore[arg-type]
839
- for key in sorted(inv_data or {}):
840
- print(key)
841
- inv_entries = sorted(inv_data[key].items())
842
- for entry, (_proj, _ver, url_path, display_name) in inv_entries:
843
- display_name = display_name * (display_name != '-')
844
- print(f' {entry:<40} {display_name:<40}: {url_path}')
845
- except ValueError as exc:
846
- print(exc.args[0] % exc.args[1:], file=sys.stderr)
847
- return 1
848
- except Exception as exc:
849
- print(f'Unknown error: {exc!r}', file=sys.stderr)
850
- return 1
851
- else:
852
- return 0
853
-
854
-
855
- if __name__ == '__main__':
856
- import logging as _logging
857
- _logging.basicConfig()
858
-
859
- raise SystemExit(inspect_main(sys.argv[1:]))
@@ -0,0 +1,53 @@
1
+ """This module contains code shared between intersphinx modules."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING, Final, Union
6
+
7
+ from sphinx.util import logging
8
+
9
+ if TYPE_CHECKING:
10
+ from sphinx.environment import BuildEnvironment
11
+ from sphinx.util.typing import Inventory
12
+
13
+ InventoryCacheEntry = tuple[Union[str, None], int, Inventory]
14
+
15
+ LOGGER: Final[logging.SphinxLoggerAdapter] = logging.getLogger('sphinx.ext.intersphinx')
16
+
17
+
18
+ class InventoryAdapter:
19
+ """Inventory adapter for environment"""
20
+
21
+ def __init__(self, env: BuildEnvironment) -> None:
22
+ self.env = env
23
+
24
+ if not hasattr(env, 'intersphinx_cache'):
25
+ # initial storage when fetching inventories before processing
26
+ self.env.intersphinx_cache = {} # type: ignore[attr-defined]
27
+
28
+ self.env.intersphinx_inventory = {} # type: ignore[attr-defined]
29
+ self.env.intersphinx_named_inventory = {} # type: ignore[attr-defined]
30
+
31
+ @property
32
+ def cache(self) -> dict[str, InventoryCacheEntry]:
33
+ """Intersphinx cache.
34
+
35
+ - Key is the URI of the remote inventory
36
+ - Element one is the key given in the Sphinx intersphinx_mapping
37
+ configuration value
38
+ - Element two is a time value for cache invalidation, a float
39
+ - Element three is the loaded remote inventory, type Inventory
40
+ """
41
+ return self.env.intersphinx_cache # type: ignore[attr-defined]
42
+
43
+ @property
44
+ def main_inventory(self) -> Inventory:
45
+ return self.env.intersphinx_inventory # type: ignore[attr-defined]
46
+
47
+ @property
48
+ def named_inventory(self) -> dict[str, Inventory]:
49
+ return self.env.intersphinx_named_inventory # type: ignore[attr-defined]
50
+
51
+ def clear(self) -> None:
52
+ self.env.intersphinx_inventory.clear() # type: ignore[attr-defined]
53
+ self.env.intersphinx_named_inventory.clear() # type: ignore[attr-defined]
sphinx/ext/mathjax.py CHANGED
@@ -25,7 +25,7 @@ if TYPE_CHECKING:
25
25
  from sphinx.writers.html import HTML5Translator
26
26
 
27
27
  # more information for mathjax secure url is here:
28
- # https://docs.mathjax.org/en/latest/start.html#secure-access-to-the-cdn
28
+ # https://docs.mathjax.org/en/latest/web/start.html#using-mathjax-from-a-content-delivery-network-cdn
29
29
  MATHJAX_URL = 'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js'
30
30
 
31
31
  logger = sphinx.util.logging.getLogger(__name__)
sphinx/ext/todo.py CHANGED
@@ -209,7 +209,7 @@ def depart_todo_node(self: HTML5Translator, node: todo_node) -> None:
209
209
 
210
210
  def latex_visit_todo_node(self: LaTeXTranslator, node: todo_node) -> None:
211
211
  if self.config.todo_include_todos:
212
- self.body.append('\n\\begin{sphinxadmonition}{note}{')
212
+ self.body.append('\n\\begin{sphinxtodo}{')
213
213
  self.body.append(self.hypertarget_to(node))
214
214
 
215
215
  title_node = cast(nodes.title, node[0])
@@ -221,7 +221,7 @@ def latex_visit_todo_node(self: LaTeXTranslator, node: todo_node) -> None:
221
221
 
222
222
 
223
223
  def latex_depart_todo_node(self: LaTeXTranslator, node: todo_node) -> None:
224
- self.body.append('\\end{sphinxadmonition}\n')
224
+ self.body.append('\\end{sphinxtodo}\n')
225
225
 
226
226
 
227
227
  def setup(app: Sphinx) -> ExtensionMetadata:
sphinx/io.py CHANGED
@@ -4,8 +4,6 @@ from __future__ import annotations
4
4
 
5
5
  from typing import TYPE_CHECKING, Any
6
6
 
7
- import docutils
8
- from docutils import nodes
9
7
  from docutils.core import Publisher
10
8
  from docutils.io import FileInput, Input, NullOutput
11
9
  from docutils.readers import standalone
@@ -25,6 +23,7 @@ from sphinx.util.docutils import LoggingReporter
25
23
  from sphinx.versioning import UIDTransform
26
24
 
27
25
  if TYPE_CHECKING:
26
+ from docutils import nodes
28
27
  from docutils.frontend import Values
29
28
  from docutils.parsers import Parser
30
29
  from docutils.transforms import Transform
@@ -191,8 +190,5 @@ def create_publisher(app: Sphinx, filetype: str) -> Publisher:
191
190
  # Propagate exceptions by default when used programmatically:
192
191
  defaults = {'traceback': True, **app.env.settings}
193
192
  # Set default settings
194
- if docutils.__version_info__[:2] >= (0, 19):
195
- pub.get_settings(**defaults)
196
- else:
197
- pub.settings = pub.setup_option_parser(**defaults).get_default_values()
193
+ pub.get_settings(**defaults)
198
194
  return pub
sphinx/locale/__init__.py CHANGED
@@ -114,11 +114,7 @@ def init(
114
114
  translator = None
115
115
 
116
116
  if language:
117
- if '_' in language:
118
- # for language having country code (like "de_AT")
119
- languages: list[str] | None = [language, language.split('_')[0]]
120
- else:
121
- languages = [language]
117
+ languages: list[str] | None = [language]
122
118
  else:
123
119
  languages = None
124
120
 
@@ -20,7 +20,7 @@ Documentation.addTranslations({
20
20
  "Go": "",
21
21
  "Hide Search Matches": "",
22
22
  "Index": "",
23
- "Index &ndash; %(key)s": "",
23
+ "Index &#x2013; %(key)s": "",
24
24
  "Index pages by letter": "",
25
25
  "Indices and tables:": "",
26
26
  "Last updated on %(last_updated)s.": "",
Binary file