Sphinx 8.0.2__py3-none-any.whl → 8.1.1__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.
- sphinx/__init__.py +6 -3
- sphinx/_cli/__init__.py +40 -20
- sphinx/_cli/util/colour.py +5 -4
- sphinx/_cli/util/errors.py +28 -11
- sphinx/application.py +361 -38
- sphinx/builders/__init__.py +229 -83
- sphinx/builders/_epub_base.py +118 -71
- sphinx/builders/changes.py +39 -21
- sphinx/builders/dirhtml.py +4 -4
- sphinx/builders/dummy.py +2 -5
- sphinx/builders/epub3.py +43 -22
- sphinx/builders/gettext.py +43 -25
- sphinx/builders/html/__init__.py +284 -218
- sphinx/builders/html/_assets.py +62 -26
- sphinx/builders/html/_build_info.py +76 -0
- sphinx/builders/html/transforms.py +11 -9
- sphinx/builders/latex/__init__.py +139 -81
- sphinx/builders/latex/constants.py +7 -7
- sphinx/builders/latex/nodes.py +3 -2
- sphinx/builders/latex/theming.py +7 -5
- sphinx/builders/latex/transforms.py +27 -19
- sphinx/builders/linkcheck.py +146 -72
- sphinx/builders/manpage.py +30 -13
- sphinx/builders/singlehtml.py +22 -14
- sphinx/builders/texinfo.py +67 -37
- sphinx/builders/text.py +5 -5
- sphinx/builders/xml.py +6 -9
- sphinx/cmd/build.py +282 -103
- sphinx/cmd/make_mode.py +106 -63
- sphinx/cmd/quickstart.py +341 -145
- sphinx/config.py +45 -12
- sphinx/deprecation.py +8 -2
- sphinx/directives/__init__.py +28 -19
- sphinx/directives/code.py +86 -56
- sphinx/directives/other.py +50 -36
- sphinx/directives/patches.py +29 -19
- sphinx/domains/__init__.py +20 -120
- sphinx/domains/_domains_container.py +281 -0
- sphinx/domains/_index.py +110 -0
- sphinx/domains/c/__init__.py +3 -3
- sphinx/domains/c/_parser.py +10 -6
- sphinx/domains/changeset.py +5 -3
- sphinx/domains/citation.py +5 -3
- sphinx/domains/cpp/__init__.py +9 -11
- sphinx/domains/cpp/_parser.py +8 -7
- sphinx/domains/index.py +3 -3
- sphinx/domains/javascript.py +12 -7
- sphinx/domains/math.py +2 -2
- sphinx/domains/python/__init__.py +10 -5
- sphinx/domains/python/_object.py +1 -1
- sphinx/domains/rst.py +5 -5
- sphinx/domains/std/__init__.py +16 -11
- sphinx/environment/__init__.py +202 -146
- sphinx/environment/adapters/asset.py +3 -2
- sphinx/environment/adapters/indexentries.py +74 -33
- sphinx/environment/adapters/toctree.py +100 -43
- sphinx/environment/collectors/__init__.py +19 -8
- sphinx/environment/collectors/asset.py +47 -15
- sphinx/environment/collectors/dependencies.py +8 -4
- sphinx/environment/collectors/metadata.py +7 -2
- sphinx/environment/collectors/title.py +7 -2
- sphinx/environment/collectors/toctree.py +54 -22
- sphinx/errors.py +4 -1
- sphinx/events.py +314 -7
- sphinx/ext/apidoc.py +42 -18
- sphinx/ext/autodoc/__init__.py +52 -24
- sphinx/ext/autodoc/importer.py +6 -9
- sphinx/ext/autosectionlabel.py +1 -2
- sphinx/ext/autosummary/__init__.py +3 -1
- sphinx/ext/autosummary/generate.py +28 -14
- sphinx/ext/coverage.py +7 -7
- sphinx/ext/doctest.py +4 -8
- sphinx/ext/duration.py +6 -5
- sphinx/ext/inheritance_diagram.py +1 -1
- sphinx/ext/intersphinx/_cli.py +6 -4
- sphinx/ext/intersphinx/_load.py +77 -32
- sphinx/ext/intersphinx/_resolve.py +173 -79
- sphinx/ext/intersphinx/_shared.py +7 -5
- sphinx/ext/linkcode.py +7 -1
- sphinx/ext/mathjax.py +1 -2
- sphinx/ext/napoleon/__init__.py +37 -24
- sphinx/ext/napoleon/docstring.py +202 -134
- sphinx/ext/todo.py +5 -3
- sphinx/highlighting.py +9 -2
- sphinx/io.py +1 -1
- sphinx/jinja2glue.py +27 -6
- sphinx/locale/__init__.py +6 -2
- sphinx/locale/ar/LC_MESSAGES/sphinx.js +8 -1
- sphinx/locale/ar/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ar/LC_MESSAGES/sphinx.po +2246 -2288
- sphinx/locale/bg/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/bg/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/bg/LC_MESSAGES/sphinx.po +2113 -2159
- sphinx/locale/bn/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/bn/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/bn/LC_MESSAGES/sphinx.po +2349 -2395
- sphinx/locale/ca/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/ca/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ca/LC_MESSAGES/sphinx.po +2846 -2892
- sphinx/locale/cak/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/cak/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cak/LC_MESSAGES/sphinx.po +2213 -2259
- sphinx/locale/cs/LC_MESSAGES/sphinx.js +6 -1
- sphinx/locale/cs/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cs/LC_MESSAGES/sphinx.po +2225 -2269
- sphinx/locale/cy/LC_MESSAGES/sphinx.js +6 -1
- sphinx/locale/cy/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cy/LC_MESSAGES/sphinx.po +2403 -2447
- sphinx/locale/da/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/da/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/da/LC_MESSAGES/sphinx.po +2214 -2260
- sphinx/locale/de/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/de/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/de/LC_MESSAGES/sphinx.po +2230 -2276
- sphinx/locale/de_DE/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/de_DE/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/de_DE/LC_MESSAGES/sphinx.po +2113 -2159
- sphinx/locale/el/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/el/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/el/LC_MESSAGES/sphinx.po +2619 -2665
- sphinx/locale/en_DE/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/en_DE/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_DE/LC_MESSAGES/sphinx.po +2113 -2159
- sphinx/locale/en_FR/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/en_FR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_FR/LC_MESSAGES/sphinx.po +2113 -2159
- sphinx/locale/en_GB/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/en_GB/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_GB/LC_MESSAGES/sphinx.po +2519 -2565
- sphinx/locale/en_HK/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/en_HK/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_HK/LC_MESSAGES/sphinx.po +2113 -2159
- sphinx/locale/eo/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/eo/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/eo/LC_MESSAGES/sphinx.po +2232 -2278
- sphinx/locale/es/LC_MESSAGES/sphinx.js +5 -1
- sphinx/locale/es/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/es/LC_MESSAGES/sphinx.po +2516 -2561
- sphinx/locale/es_CO/LC_MESSAGES/sphinx.js +5 -1
- sphinx/locale/es_CO/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/es_CO/LC_MESSAGES/sphinx.po +2114 -2159
- sphinx/locale/et/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/et/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/et/LC_MESSAGES/sphinx.po +2317 -2363
- sphinx/locale/eu/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/eu/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/eu/LC_MESSAGES/sphinx.po +2218 -2264
- sphinx/locale/fa/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/fa/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fa/LC_MESSAGES/sphinx.po +2505 -2551
- sphinx/locale/fi/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/fi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fi/LC_MESSAGES/sphinx.po +2303 -2349
- sphinx/locale/fr/LC_MESSAGES/sphinx.js +6 -2
- sphinx/locale/fr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fr/LC_MESSAGES/sphinx.po +2863 -2908
- sphinx/locale/fr_FR/LC_MESSAGES/sphinx.js +5 -1
- sphinx/locale/fr_FR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fr_FR/LC_MESSAGES/sphinx.po +2114 -2159
- sphinx/locale/gl/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/gl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/gl/LC_MESSAGES/sphinx.po +2571 -2617
- sphinx/locale/he/LC_MESSAGES/sphinx.js +5 -1
- sphinx/locale/he/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/he/LC_MESSAGES/sphinx.po +2307 -2352
- sphinx/locale/hi/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/hi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hi/LC_MESSAGES/sphinx.po +2580 -2626
- sphinx/locale/hi_IN/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/hi_IN/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hi_IN/LC_MESSAGES/sphinx.po +2113 -2159
- sphinx/locale/hr/LC_MESSAGES/sphinx.js +5 -1
- sphinx/locale/hr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hr/LC_MESSAGES/sphinx.po +2238 -2283
- sphinx/locale/hu/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/hu/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hu/LC_MESSAGES/sphinx.po +2228 -2274
- sphinx/locale/id/LC_MESSAGES/sphinx.js +3 -1
- sphinx/locale/id/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/id/LC_MESSAGES/sphinx.po +2787 -2834
- sphinx/locale/is/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/is/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/is/LC_MESSAGES/sphinx.po +2224 -2270
- sphinx/locale/it/LC_MESSAGES/sphinx.js +5 -1
- sphinx/locale/it/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/it/LC_MESSAGES/sphinx.po +2231 -2276
- sphinx/locale/ja/LC_MESSAGES/sphinx.js +3 -1
- sphinx/locale/ja/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ja/LC_MESSAGES/sphinx.po +2507 -2554
- sphinx/locale/ka/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/ka/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ka/LC_MESSAGES/sphinx.po +2428 -2474
- sphinx/locale/ko/LC_MESSAGES/sphinx.js +3 -1
- sphinx/locale/ko/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ko/LC_MESSAGES/sphinx.po +2516 -2563
- sphinx/locale/lt/LC_MESSAGES/sphinx.js +6 -1
- sphinx/locale/lt/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/lt/LC_MESSAGES/sphinx.po +2425 -2469
- sphinx/locale/lv/LC_MESSAGES/sphinx.js +5 -1
- sphinx/locale/lv/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/lv/LC_MESSAGES/sphinx.po +2362 -2407
- sphinx/locale/mk/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/mk/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/mk/LC_MESSAGES/sphinx.po +2121 -2167
- sphinx/locale/nb_NO/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/nb_NO/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po +2220 -2266
- sphinx/locale/ne/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/ne/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ne/LC_MESSAGES/sphinx.po +2221 -2267
- sphinx/locale/nl/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/nl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/nl/LC_MESSAGES/sphinx.po +2240 -2286
- sphinx/locale/pl/LC_MESSAGES/sphinx.js +6 -1
- sphinx/locale/pl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pl/LC_MESSAGES/sphinx.po +2319 -2363
- sphinx/locale/pt/LC_MESSAGES/sphinx.js +5 -1
- sphinx/locale/pt/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt/LC_MESSAGES/sphinx.po +2114 -2159
- sphinx/locale/pt_BR/LC_MESSAGES/sphinx.js +5 -1
- sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po +2854 -2899
- sphinx/locale/pt_PT/LC_MESSAGES/sphinx.js +5 -1
- sphinx/locale/pt_PT/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt_PT/LC_MESSAGES/sphinx.po +2224 -2269
- sphinx/locale/ro/LC_MESSAGES/sphinx.js +5 -1
- sphinx/locale/ro/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ro/LC_MESSAGES/sphinx.po +2226 -2271
- sphinx/locale/ru/LC_MESSAGES/sphinx.js +8 -3
- sphinx/locale/ru/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ru/LC_MESSAGES/sphinx.po +2841 -2885
- sphinx/locale/si/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/si/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/si/LC_MESSAGES/sphinx.po +2294 -2340
- sphinx/locale/sk/LC_MESSAGES/sphinx.js +6 -1
- sphinx/locale/sk/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sk/LC_MESSAGES/sphinx.po +2497 -2541
- sphinx/locale/sl/LC_MESSAGES/sphinx.js +6 -1
- sphinx/locale/sl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sl/LC_MESSAGES/sphinx.po +2331 -2375
- sphinx/locale/sphinx.pot +2121 -2167
- sphinx/locale/sq/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/sq/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sq/LC_MESSAGES/sphinx.po +2855 -2901
- sphinx/locale/sr/LC_MESSAGES/sphinx.js +5 -1
- sphinx/locale/sr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sr/LC_MESSAGES/sphinx.po +2203 -2248
- sphinx/locale/sr@latin/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sr_RS/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sv/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/sv/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sv/LC_MESSAGES/sphinx.po +2423 -2469
- sphinx/locale/te/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/te/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/te/LC_MESSAGES/sphinx.po +2113 -2159
- sphinx/locale/tr/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/tr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/tr/LC_MESSAGES/sphinx.po +2443 -2489
- sphinx/locale/uk_UA/LC_MESSAGES/sphinx.js +6 -1
- sphinx/locale/uk_UA/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po +2329 -2373
- sphinx/locale/ur/LC_MESSAGES/sphinx.js +4 -1
- sphinx/locale/ur/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ur/LC_MESSAGES/sphinx.po +2113 -2159
- sphinx/locale/vi/LC_MESSAGES/sphinx.js +3 -1
- sphinx/locale/vi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/vi/LC_MESSAGES/sphinx.po +2199 -2246
- sphinx/locale/yue/LC_MESSAGES/sphinx.js +3 -1
- sphinx/locale/yue/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/yue/LC_MESSAGES/sphinx.po +2112 -2159
- sphinx/locale/zh_HK/LC_MESSAGES/sphinx.js +3 -1
- sphinx/locale/zh_HK/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_HK/LC_MESSAGES/sphinx.po +2112 -2159
- sphinx/locale/zh_TW/LC_MESSAGES/sphinx.js +3 -1
- sphinx/locale/zh_TW/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po +2845 -2892
- sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.js +3 -1
- sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.po +2112 -2159
- sphinx/parsers.py +3 -1
- sphinx/project.py +6 -2
- sphinx/pycode/__init__.py +11 -4
- sphinx/pycode/ast.py +58 -58
- sphinx/pycode/parser.py +49 -28
- sphinx/pygments_styles.py +49 -49
- sphinx/registry.py +8 -3
- sphinx/roles.py +136 -13
- sphinx/search/__init__.py +146 -87
- sphinx/search/da.py +2 -4
- sphinx/search/de.py +2 -4
- sphinx/search/en.py +4 -4
- sphinx/search/es.py +2 -4
- sphinx/search/fi.py +2 -4
- sphinx/search/fr.py +2 -4
- sphinx/search/hu.py +2 -4
- sphinx/search/it.py +2 -4
- sphinx/search/ja.py +55 -32
- sphinx/search/nl.py +2 -4
- sphinx/search/no.py +2 -4
- sphinx/search/pt.py +2 -4
- sphinx/search/ro.py +0 -2
- sphinx/search/ru.py +2 -4
- sphinx/search/sv.py +2 -4
- sphinx/search/tr.py +0 -2
- sphinx/search/zh.py +18 -13
- sphinx/templates/graphviz/graphviz.css +0 -7
- sphinx/testing/fixtures.py +6 -5
- sphinx/testing/path.py +7 -5
- sphinx/testing/util.py +63 -29
- sphinx/texinputs/sphinx.sty +115 -50
- sphinx/texinputs/sphinxlatexadmonitions.sty +56 -38
- sphinx/texinputs/sphinxlatexcontainers.sty +1 -1
- sphinx/texinputs/sphinxlatexgraphics.sty +3 -2
- sphinx/texinputs/sphinxlatexindbibtoc.sty +1 -1
- sphinx/texinputs/sphinxlatexlists.sty +1 -1
- sphinx/texinputs/sphinxlatexliterals.sty +4 -1
- sphinx/texinputs/sphinxlatexnumfig.sty +22 -9
- sphinx/texinputs/sphinxlatexobjects.sty +1 -1
- sphinx/texinputs/sphinxlatexshadowbox.sty +72 -10
- sphinx/texinputs/sphinxlatexstyleheadings.sty +7 -2
- sphinx/texinputs/sphinxlatexstylepage.sty +2 -8
- sphinx/texinputs/sphinxlatexstyletext.sty +2 -4
- sphinx/texinputs/sphinxlatextables.sty +1 -1
- sphinx/texinputs/sphinxoptionsgeometry.sty +1 -1
- sphinx/texinputs/sphinxoptionshyperref.sty +1 -1
- sphinx/themes/agogo/layout.html +1 -10
- sphinx/themes/agogo/static/agogo.css.jinja +0 -7
- sphinx/themes/basic/defindex.html +1 -8
- sphinx/themes/basic/domainindex.html +1 -9
- sphinx/themes/basic/genindex-single.html +1 -9
- sphinx/themes/basic/genindex-split.html +1 -9
- sphinx/themes/basic/genindex.html +1 -9
- sphinx/themes/basic/globaltoc.html +1 -9
- sphinx/themes/basic/layout.html +1 -9
- sphinx/themes/basic/localtoc.html +1 -9
- sphinx/themes/basic/page.html +1 -9
- sphinx/themes/basic/relations.html +1 -9
- sphinx/themes/basic/search.html +1 -9
- sphinx/themes/basic/searchbox.html +1 -9
- sphinx/themes/basic/searchfield.html +4 -10
- sphinx/themes/basic/sourcelink.html +1 -9
- sphinx/themes/basic/static/basic.css.jinja +2 -13
- sphinx/themes/basic/static/doctools.js +0 -7
- sphinx/themes/basic/static/language_data.js.jinja +0 -7
- sphinx/themes/basic/static/searchtools.js +25 -13
- sphinx/themes/bizstyle/layout.html +1 -9
- sphinx/themes/bizstyle/static/bizstyle.css.jinja +0 -7
- sphinx/themes/bizstyle/static/bizstyle.js.jinja +5 -11
- sphinx/themes/classic/layout.html +1 -9
- sphinx/themes/classic/static/classic.css.jinja +0 -7
- sphinx/themes/classic/static/sidebar.js.jinja +0 -6
- sphinx/themes/epub/epub-cover.html +1 -9
- sphinx/themes/epub/layout.html +1 -9
- sphinx/themes/epub/static/epub.css.jinja +0 -7
- sphinx/themes/haiku/layout.html +1 -9
- sphinx/themes/haiku/static/haiku.css.jinja +0 -6
- sphinx/themes/nature/static/nature.css.jinja +0 -7
- sphinx/themes/nonav/layout.html +1 -9
- sphinx/themes/nonav/static/nonav.css.jinja +0 -7
- sphinx/themes/pyramid/static/epub.css.jinja +0 -7
- sphinx/themes/pyramid/static/pyramid.css.jinja +0 -7
- sphinx/themes/scrolls/layout.html +1 -10
- sphinx/themes/scrolls/static/scrolls.css.jinja +0 -7
- sphinx/themes/sphinxdoc/static/sphinxdoc.css.jinja +2 -7
- sphinx/themes/traditional/static/traditional.css.jinja +0 -7
- sphinx/theming.py +18 -6
- sphinx/transforms/__init__.py +56 -35
- sphinx/transforms/compact_bullet_list.py +3 -2
- sphinx/transforms/i18n.py +132 -50
- sphinx/transforms/post_transforms/__init__.py +94 -43
- sphinx/transforms/post_transforms/code.py +7 -6
- sphinx/transforms/post_transforms/images.py +71 -54
- sphinx/transforms/references.py +1 -2
- sphinx/util/__init__.py +23 -194
- sphinx/util/_files.py +80 -0
- sphinx/util/_importer.py +27 -0
- sphinx/util/_io.py +1 -2
- sphinx/util/_lines.py +26 -0
- sphinx/util/_pathlib.py +5 -2
- sphinx/util/_serialise.py +53 -0
- sphinx/util/_timestamps.py +2 -1
- sphinx/util/_uri.py +16 -0
- sphinx/util/cfamily.py +48 -25
- sphinx/util/console.py +1 -0
- sphinx/util/display.py +1 -1
- sphinx/util/docfields.py +125 -45
- sphinx/util/docstrings.py +1 -1
- sphinx/util/docutils.py +118 -44
- sphinx/util/exceptions.py +11 -5
- sphinx/util/fileutil.py +53 -32
- sphinx/util/http_date.py +9 -7
- sphinx/util/i18n.py +49 -16
- sphinx/util/images.py +7 -6
- sphinx/util/inspect.py +29 -12
- sphinx/util/inventory.py +47 -29
- sphinx/util/logging.py +58 -85
- sphinx/util/matching.py +3 -3
- sphinx/util/math.py +1 -1
- sphinx/util/nodes.py +176 -108
- sphinx/util/osutil.py +13 -10
- sphinx/util/parallel.py +5 -4
- sphinx/util/parsing.py +5 -3
- sphinx/util/png.py +3 -3
- sphinx/util/requests.py +8 -4
- sphinx/util/rst.py +5 -3
- sphinx/util/tags.py +5 -2
- sphinx/util/template.py +26 -11
- sphinx/util/texescape.py +2 -2
- sphinx/util/typing.py +89 -38
- sphinx/versioning.py +3 -1
- sphinx/writers/html.py +22 -7
- sphinx/writers/html5.py +113 -64
- sphinx/writers/latex.py +408 -221
- sphinx/writers/manpage.py +25 -15
- sphinx/writers/texinfo.py +94 -82
- sphinx/writers/text.py +87 -53
- sphinx/writers/xml.py +5 -4
- sphinx-8.1.1.dist-info/LICENSE.rst +31 -0
- {sphinx-8.0.2.dist-info → sphinx-8.1.1.dist-info}/METADATA +13 -11
- sphinx-8.1.1.dist-info/RECORD +598 -0
- sphinx-8.0.2.dist-info/LICENSE.rst +0 -67
- sphinx-8.0.2.dist-info/RECORD +0 -590
- {sphinx-8.0.2.dist-info → sphinx-8.1.1.dist-info}/WHEEL +0 -0
- {sphinx-8.0.2.dist-info → sphinx-8.1.1.dist-info}/entry_points.txt +0 -0
sphinx/environment/__init__.py
CHANGED
|
@@ -8,14 +8,22 @@ import pickle
|
|
|
8
8
|
from collections import defaultdict
|
|
9
9
|
from copy import copy
|
|
10
10
|
from os import path
|
|
11
|
-
from typing import TYPE_CHECKING
|
|
11
|
+
from typing import TYPE_CHECKING
|
|
12
12
|
|
|
13
13
|
from sphinx import addnodes
|
|
14
|
+
from sphinx.domains._domains_container import _DomainsContainer
|
|
14
15
|
from sphinx.environment.adapters import toctree as toctree_adapters
|
|
15
|
-
from sphinx.errors import
|
|
16
|
+
from sphinx.errors import (
|
|
17
|
+
BuildEnvironmentError,
|
|
18
|
+
DocumentError,
|
|
19
|
+
ExtensionError,
|
|
20
|
+
SphinxError,
|
|
21
|
+
)
|
|
16
22
|
from sphinx.locale import __
|
|
17
23
|
from sphinx.transforms import SphinxTransformer
|
|
18
|
-
from sphinx.util import
|
|
24
|
+
from sphinx.util import logging
|
|
25
|
+
from sphinx.util._files import DownloadFiles, FilenameUniqDict
|
|
26
|
+
from sphinx.util._serialise import stable_str
|
|
19
27
|
from sphinx.util._timestamps import _format_rfc3339_microseconds
|
|
20
28
|
from sphinx.util.docutils import LoggingReporter
|
|
21
29
|
from sphinx.util.i18n import CatalogRepository, docname_to_domain
|
|
@@ -23,8 +31,9 @@ from sphinx.util.nodes import is_translatable
|
|
|
23
31
|
from sphinx.util.osutil import _last_modified_time, canon_path, os_path
|
|
24
32
|
|
|
25
33
|
if TYPE_CHECKING:
|
|
26
|
-
from collections.abc import Callable, Iterator
|
|
34
|
+
from collections.abc import Callable, Iterable, Iterator
|
|
27
35
|
from pathlib import Path
|
|
36
|
+
from typing import Any, Literal
|
|
28
37
|
|
|
29
38
|
from docutils import nodes
|
|
30
39
|
from docutils.nodes import Node
|
|
@@ -60,7 +69,7 @@ default_settings: dict[str, Any] = {
|
|
|
60
69
|
|
|
61
70
|
# This is increased every time an environment attribute is added
|
|
62
71
|
# or changed to properly invalidate pickle files.
|
|
63
|
-
ENV_VERSION =
|
|
72
|
+
ENV_VERSION = 64
|
|
64
73
|
|
|
65
74
|
# config status
|
|
66
75
|
CONFIG_UNSET = -1
|
|
@@ -81,61 +90,6 @@ versioning_conditions: dict[str, Literal[False] | Callable[[Node], bool]] = {
|
|
|
81
90
|
'text': is_translatable,
|
|
82
91
|
}
|
|
83
92
|
|
|
84
|
-
if TYPE_CHECKING:
|
|
85
|
-
from collections.abc import MutableMapping
|
|
86
|
-
from typing import Literal, overload
|
|
87
|
-
|
|
88
|
-
from sphinx.domains.c import CDomain
|
|
89
|
-
from sphinx.domains.changeset import ChangeSetDomain
|
|
90
|
-
from sphinx.domains.citation import CitationDomain
|
|
91
|
-
from sphinx.domains.cpp import CPPDomain
|
|
92
|
-
from sphinx.domains.index import IndexDomain
|
|
93
|
-
from sphinx.domains.javascript import JavaScriptDomain
|
|
94
|
-
from sphinx.domains.math import MathDomain
|
|
95
|
-
from sphinx.domains.python import PythonDomain
|
|
96
|
-
from sphinx.domains.rst import ReSTDomain
|
|
97
|
-
from sphinx.domains.std import StandardDomain
|
|
98
|
-
from sphinx.ext.duration import DurationDomain
|
|
99
|
-
from sphinx.ext.todo import TodoDomain
|
|
100
|
-
|
|
101
|
-
class _DomainsType(MutableMapping[str, Domain]):
|
|
102
|
-
@overload
|
|
103
|
-
def __getitem__(self, key: Literal["c"]) -> CDomain: ... # NoQA: E704
|
|
104
|
-
@overload
|
|
105
|
-
def __getitem__(self, key: Literal["cpp"]) -> CPPDomain: ... # NoQA: E704
|
|
106
|
-
@overload
|
|
107
|
-
def __getitem__(self, key: Literal["changeset"]) -> ChangeSetDomain: ... # NoQA: E704
|
|
108
|
-
@overload
|
|
109
|
-
def __getitem__(self, key: Literal["citation"]) -> CitationDomain: ... # NoQA: E704
|
|
110
|
-
@overload
|
|
111
|
-
def __getitem__(self, key: Literal["index"]) -> IndexDomain: ... # NoQA: E704
|
|
112
|
-
@overload
|
|
113
|
-
def __getitem__(self, key: Literal["js"]) -> JavaScriptDomain: ... # NoQA: E704
|
|
114
|
-
@overload
|
|
115
|
-
def __getitem__(self, key: Literal["math"]) -> MathDomain: ... # NoQA: E704
|
|
116
|
-
@overload
|
|
117
|
-
def __getitem__(self, key: Literal["py"]) -> PythonDomain: ... # NoQA: E704
|
|
118
|
-
@overload
|
|
119
|
-
def __getitem__(self, key: Literal["rst"]) -> ReSTDomain: ... # NoQA: E704
|
|
120
|
-
@overload
|
|
121
|
-
def __getitem__(self, key: Literal["std"]) -> StandardDomain: ... # NoQA: E704
|
|
122
|
-
@overload
|
|
123
|
-
def __getitem__(self, key: Literal["duration"]) -> DurationDomain: ... # NoQA: E704
|
|
124
|
-
@overload
|
|
125
|
-
def __getitem__(self, key: Literal["todo"]) -> TodoDomain: ... # NoQA: E704
|
|
126
|
-
@overload
|
|
127
|
-
def __getitem__(self, key: str) -> Domain: ... # NoQA: E704
|
|
128
|
-
def __getitem__(self, _key: str) -> Domain: raise NotImplementedError # NoQA: E704
|
|
129
|
-
def __setitem__( # NoQA: E301,E704
|
|
130
|
-
self, key: str, value: Domain,
|
|
131
|
-
) -> NoReturn: raise NotImplementedError
|
|
132
|
-
def __delitem__(self, key: str) -> NoReturn: raise NotImplementedError # NoQA: E704
|
|
133
|
-
def __iter__(self) -> NoReturn: raise NotImplementedError # NoQA: E704
|
|
134
|
-
def __len__(self) -> NoReturn: raise NotImplementedError # NoQA: E704
|
|
135
|
-
|
|
136
|
-
else:
|
|
137
|
-
_DomainsType = dict
|
|
138
|
-
|
|
139
93
|
|
|
140
94
|
class BuildEnvironment:
|
|
141
95
|
"""
|
|
@@ -144,8 +98,6 @@ class BuildEnvironment:
|
|
|
144
98
|
transformations to resolve links to them.
|
|
145
99
|
"""
|
|
146
100
|
|
|
147
|
-
domains: _DomainsType
|
|
148
|
-
|
|
149
101
|
# --------- ENVIRONMENT INITIALIZATION -------------------------------------
|
|
150
102
|
|
|
151
103
|
def __init__(self, app: Sphinx) -> None:
|
|
@@ -163,9 +115,6 @@ class BuildEnvironment:
|
|
|
163
115
|
self.versioning_condition: Literal[False] | Callable[[Node], bool] | None = None
|
|
164
116
|
self.versioning_compare: bool | None = None
|
|
165
117
|
|
|
166
|
-
# all the registered domains, set by the application
|
|
167
|
-
self.domains = _DomainsType()
|
|
168
|
-
|
|
169
118
|
# the docutils settings for building
|
|
170
119
|
self.settings: dict[str, Any] = default_settings.copy()
|
|
171
120
|
self.settings['env'] = self
|
|
@@ -242,7 +191,7 @@ class BuildEnvironment:
|
|
|
242
191
|
self.dlfiles: DownloadFiles = DownloadFiles()
|
|
243
192
|
|
|
244
193
|
# the original URI for images
|
|
245
|
-
self.original_image_uri: dict[
|
|
194
|
+
self.original_image_uri: dict[_StrPath, str] = {}
|
|
246
195
|
|
|
247
196
|
# temporary data storage while reading a document
|
|
248
197
|
self.temp_data: dict[str, Any] = {}
|
|
@@ -270,6 +219,9 @@ class BuildEnvironment:
|
|
|
270
219
|
# objtype index -> (domain, type, objname (localized))
|
|
271
220
|
self._search_index_objnames: dict[int, tuple[str, str, str]] = {}
|
|
272
221
|
|
|
222
|
+
# all the registered domains, set by the application
|
|
223
|
+
self.domains: _DomainsContainer = _DomainsContainer._from_environment(self)
|
|
224
|
+
|
|
273
225
|
# set up environment
|
|
274
226
|
self.setup(app)
|
|
275
227
|
|
|
@@ -277,7 +229,7 @@ class BuildEnvironment:
|
|
|
277
229
|
"""Obtains serializable data for pickling."""
|
|
278
230
|
__dict__ = self.__dict__.copy()
|
|
279
231
|
# clear unpickable attributes
|
|
280
|
-
__dict__.update(app=None, domains=
|
|
232
|
+
__dict__.update(app=None, domains=None, events=None)
|
|
281
233
|
# clear in-memory doctree caches, to reduce memory consumption and
|
|
282
234
|
# ensure that, upon restoring the state, the most recent pickled files
|
|
283
235
|
# on the disk are used instead of those from a possibly outdated state
|
|
@@ -304,51 +256,83 @@ class BuildEnvironment:
|
|
|
304
256
|
self.project = app.project
|
|
305
257
|
self.version = app.registry.get_envversion(app)
|
|
306
258
|
|
|
307
|
-
#
|
|
308
|
-
self.domains
|
|
309
|
-
|
|
310
|
-
self.domains
|
|
311
|
-
|
|
259
|
+
# initialise domains
|
|
260
|
+
if self.domains is None:
|
|
261
|
+
# if we are unpickling an environment, we need to recreate the domains
|
|
262
|
+
self.domains = _DomainsContainer._from_environment(self)
|
|
312
263
|
# setup domains (must do after all initialization)
|
|
313
|
-
|
|
314
|
-
domain.setup()
|
|
264
|
+
self.domains._setup()
|
|
315
265
|
|
|
316
|
-
#
|
|
317
|
-
self.
|
|
266
|
+
# Initialise config.
|
|
267
|
+
# The old config is self.config, restored from the pickled environment.
|
|
268
|
+
# The new config is app.config, always recreated from ``conf.py``
|
|
269
|
+
self.config_status, self.config_status_extra = self._config_status(
|
|
270
|
+
old_config=self.config, new_config=app.config, verbosity=app.verbosity
|
|
271
|
+
)
|
|
272
|
+
self.config = app.config
|
|
318
273
|
|
|
319
274
|
# initialize settings
|
|
320
275
|
self._update_settings(app.config)
|
|
321
276
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
277
|
+
@staticmethod
|
|
278
|
+
def _config_status(
|
|
279
|
+
*, old_config: Config | None, new_config: Config, verbosity: int
|
|
280
|
+
) -> tuple[int, str]:
|
|
281
|
+
"""Report the differences between two Config objects.
|
|
282
|
+
|
|
283
|
+
Returns a triple of:
|
|
284
|
+
|
|
285
|
+
1. The new configuration
|
|
286
|
+
2. A status code indicating how the configuration has changed.
|
|
287
|
+
3. A status message indicating what has changed.
|
|
288
|
+
"""
|
|
289
|
+
if old_config is None:
|
|
290
|
+
return CONFIG_NEW, ''
|
|
291
|
+
|
|
292
|
+
if old_config.extensions != new_config.extensions:
|
|
293
|
+
old_extensions = set(old_config.extensions)
|
|
294
|
+
new_extensions = set(new_config.extensions)
|
|
295
|
+
extensions = old_extensions ^ new_extensions
|
|
332
296
|
if len(extensions) == 1:
|
|
333
|
-
extension = extensions
|
|
297
|
+
extension = extensions.pop()
|
|
334
298
|
else:
|
|
335
|
-
extension = '
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
299
|
+
extension = f'{len(extensions)}'
|
|
300
|
+
return CONFIG_EXTENSIONS_CHANGED, f' ({extension!r})'
|
|
301
|
+
|
|
302
|
+
# Log any changes in configuration keys
|
|
303
|
+
if changed_keys := _differing_config_keys(old_config, new_config):
|
|
304
|
+
changed_num = len(changed_keys)
|
|
305
|
+
if changed_num == 1:
|
|
306
|
+
logger.info(
|
|
307
|
+
__('The configuration has changed (1 option: %r)'),
|
|
308
|
+
next(iter(changed_keys)),
|
|
309
|
+
)
|
|
310
|
+
elif changed_num <= 5 or verbosity >= 1:
|
|
311
|
+
logger.info(
|
|
312
|
+
__('The configuration has changed (%d options: %s)'),
|
|
313
|
+
changed_num,
|
|
314
|
+
', '.join(map(repr, sorted(changed_keys))),
|
|
315
|
+
)
|
|
316
|
+
else:
|
|
317
|
+
logger.info(
|
|
318
|
+
__('The configuration has changed (%d options: %s, ...)'),
|
|
319
|
+
changed_num,
|
|
320
|
+
', '.join(map(repr, sorted(changed_keys)[:5])),
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
# check if a config value was changed that affects how doctrees are read
|
|
324
|
+
for item in new_config.filter(frozenset({'env'})):
|
|
325
|
+
if old_config[item.name] != item.value:
|
|
326
|
+
return CONFIG_CHANGED, f' ({item.name!r})'
|
|
345
327
|
|
|
346
|
-
|
|
328
|
+
return CONFIG_OK, ''
|
|
347
329
|
|
|
348
330
|
def _update_settings(self, config: Config) -> None:
|
|
349
331
|
"""Update settings by new config."""
|
|
350
332
|
self.settings['input_encoding'] = config.source_encoding
|
|
351
|
-
self.settings['trim_footnote_reference_space'] =
|
|
333
|
+
self.settings['trim_footnote_reference_space'] = (
|
|
334
|
+
config.trim_footnote_reference_space
|
|
335
|
+
)
|
|
352
336
|
self.settings['language_code'] = config.language
|
|
353
337
|
|
|
354
338
|
# Allow to disable by 3rd party extension (workaround)
|
|
@@ -373,9 +357,12 @@ class BuildEnvironment:
|
|
|
373
357
|
condition = versioning_conditions[method]
|
|
374
358
|
|
|
375
359
|
if self.versioning_condition not in {None, condition}:
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
360
|
+
msg = __(
|
|
361
|
+
'This environment is incompatible with the '
|
|
362
|
+
'selected builder, please choose another '
|
|
363
|
+
'doctree directory.'
|
|
364
|
+
)
|
|
365
|
+
raise SphinxError(msg)
|
|
379
366
|
self.versioning_condition = condition
|
|
380
367
|
self.versioning_compare = compare
|
|
381
368
|
|
|
@@ -386,25 +373,24 @@ class BuildEnvironment:
|
|
|
386
373
|
self.included.pop(docname, None)
|
|
387
374
|
self.reread_always.discard(docname)
|
|
388
375
|
|
|
389
|
-
|
|
390
|
-
domain.clear_doc(docname)
|
|
376
|
+
self.domains._clear_doc(docname)
|
|
391
377
|
|
|
392
|
-
def merge_info_from(
|
|
393
|
-
|
|
378
|
+
def merge_info_from(
|
|
379
|
+
self, docnames: Iterable[str], other: BuildEnvironment, app: Sphinx
|
|
380
|
+
) -> None:
|
|
394
381
|
"""Merge global information gathered about *docnames* while reading them
|
|
395
382
|
from the *other* environment.
|
|
396
383
|
|
|
397
384
|
This possibly comes from a parallel build process.
|
|
398
385
|
"""
|
|
399
|
-
docnames =
|
|
386
|
+
docnames = frozenset(docnames)
|
|
400
387
|
for docname in docnames:
|
|
401
388
|
self.all_docs[docname] = other.all_docs[docname]
|
|
402
389
|
self.included[docname] = other.included[docname]
|
|
403
390
|
if docname in other.reread_always:
|
|
404
391
|
self.reread_always.add(docname)
|
|
405
392
|
|
|
406
|
-
|
|
407
|
-
domain.merge_domaindata(docnames, other.domaindata[domainname])
|
|
393
|
+
self.domains._merge_domain_data(docnames, other.domaindata)
|
|
408
394
|
self.events.emit('env-merge-info', self, docnames, other)
|
|
409
395
|
|
|
410
396
|
def path2doc(self, filename: str | os.PathLike[str]) -> str | None:
|
|
@@ -434,12 +420,13 @@ class BuildEnvironment:
|
|
|
434
420
|
if filename.startswith(('/', os.sep)):
|
|
435
421
|
rel_fn = filename[1:]
|
|
436
422
|
else:
|
|
437
|
-
docdir = path.dirname(self.doc2path(docname or self.docname,
|
|
438
|
-
base=False))
|
|
423
|
+
docdir = path.dirname(self.doc2path(docname or self.docname, base=False))
|
|
439
424
|
rel_fn = path.join(docdir, filename)
|
|
440
425
|
|
|
441
|
-
return (
|
|
442
|
-
|
|
426
|
+
return (
|
|
427
|
+
canon_path(path.normpath(rel_fn)),
|
|
428
|
+
path.normpath(path.join(self.srcdir, rel_fn)),
|
|
429
|
+
)
|
|
443
430
|
|
|
444
431
|
@property
|
|
445
432
|
def found_docs(self) -> set[str]:
|
|
@@ -451,9 +438,11 @@ class BuildEnvironment:
|
|
|
451
438
|
self.found_docs.
|
|
452
439
|
"""
|
|
453
440
|
try:
|
|
454
|
-
exclude_paths = (
|
|
455
|
-
|
|
456
|
-
|
|
441
|
+
exclude_paths = (
|
|
442
|
+
self.config.exclude_patterns
|
|
443
|
+
+ self.config.templates_path
|
|
444
|
+
+ builder.get_asset_paths()
|
|
445
|
+
)
|
|
457
446
|
self.project.discover(exclude_paths, self.config.include_patterns)
|
|
458
447
|
|
|
459
448
|
# Current implementation is applying translated messages in the reading
|
|
@@ -464,18 +453,25 @@ class BuildEnvironment:
|
|
|
464
453
|
# move i18n process into the writing phase, and remove these lines.
|
|
465
454
|
if builder.use_message_catalog:
|
|
466
455
|
# add catalog mo file dependency
|
|
467
|
-
repo = CatalogRepository(
|
|
468
|
-
|
|
456
|
+
repo = CatalogRepository(
|
|
457
|
+
self.srcdir,
|
|
458
|
+
self.config.locale_dirs,
|
|
459
|
+
self.config.language,
|
|
460
|
+
self.config.source_encoding,
|
|
461
|
+
)
|
|
469
462
|
mo_paths = {c.domain: c.mo_path for c in repo.catalogs}
|
|
470
463
|
for docname in self.found_docs:
|
|
471
464
|
domain = docname_to_domain(docname, self.config.gettext_compact)
|
|
472
465
|
if domain in mo_paths:
|
|
473
466
|
self.dependencies[docname].add(mo_paths[domain])
|
|
474
467
|
except OSError as exc:
|
|
475
|
-
raise DocumentError(
|
|
476
|
-
|
|
468
|
+
raise DocumentError(
|
|
469
|
+
__('Failed to scan documents in %s: %r') % (self.srcdir, exc)
|
|
470
|
+
) from exc
|
|
477
471
|
|
|
478
|
-
def get_outdated_files(
|
|
472
|
+
def get_outdated_files(
|
|
473
|
+
self, config_changed: bool
|
|
474
|
+
) -> tuple[set[str], set[str], set[str]]:
|
|
479
475
|
"""Return (added, changed, removed) sets."""
|
|
480
476
|
# clear all files no longer present
|
|
481
477
|
removed = set(self.all_docs) - self.found_docs
|
|
@@ -507,10 +503,12 @@ class BuildEnvironment:
|
|
|
507
503
|
mtime = self.all_docs[docname]
|
|
508
504
|
newmtime = _last_modified_time(self.doc2path(docname))
|
|
509
505
|
if newmtime > mtime:
|
|
510
|
-
logger.debug(
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
506
|
+
logger.debug(
|
|
507
|
+
'[build target] outdated %r: %s -> %s',
|
|
508
|
+
docname,
|
|
509
|
+
_format_rfc3339_microseconds(mtime),
|
|
510
|
+
_format_rfc3339_microseconds(newmtime),
|
|
511
|
+
)
|
|
514
512
|
changed.add(docname)
|
|
515
513
|
continue
|
|
516
514
|
# finally, check the mtime of dependencies
|
|
@@ -521,7 +519,8 @@ class BuildEnvironment:
|
|
|
521
519
|
if not path.isfile(deppath):
|
|
522
520
|
logger.debug(
|
|
523
521
|
'[build target] changed %r missing dependency %r',
|
|
524
|
-
docname,
|
|
522
|
+
docname,
|
|
523
|
+
deppath,
|
|
525
524
|
)
|
|
526
525
|
changed.add(docname)
|
|
527
526
|
break
|
|
@@ -529,7 +528,8 @@ class BuildEnvironment:
|
|
|
529
528
|
if depmtime > mtime:
|
|
530
529
|
logger.debug(
|
|
531
530
|
'[build target] outdated %r from dependency %r: %s -> %s',
|
|
532
|
-
docname,
|
|
531
|
+
docname,
|
|
532
|
+
deppath,
|
|
533
533
|
_format_rfc3339_microseconds(mtime),
|
|
534
534
|
_format_rfc3339_microseconds(depmtime),
|
|
535
535
|
)
|
|
@@ -557,8 +557,7 @@ class BuildEnvironment:
|
|
|
557
557
|
self.temp_data['docname'] = docname
|
|
558
558
|
# defaults to the global default, but can be re-set in a document
|
|
559
559
|
self.temp_data['default_role'] = self.config.default_role
|
|
560
|
-
self.temp_data['default_domain'] =
|
|
561
|
-
self.domains.get(self.config.primary_domain)
|
|
560
|
+
self.temp_data['default_domain'] = self.domains.get(self.config.primary_domain)
|
|
562
561
|
|
|
563
562
|
# utilities to use while reading a document
|
|
564
563
|
|
|
@@ -616,7 +615,8 @@ class BuildEnvironment:
|
|
|
616
615
|
try:
|
|
617
616
|
return self.domains[domainname]
|
|
618
617
|
except KeyError as exc:
|
|
619
|
-
|
|
618
|
+
msg = __('Domain %r is not registered') % domainname
|
|
619
|
+
raise ExtensionError(msg) from exc
|
|
620
620
|
|
|
621
621
|
# --------- RESOLVING REFERENCES AND TOCTREES ------------------------------
|
|
622
622
|
|
|
@@ -663,7 +663,10 @@ class BuildEnvironment:
|
|
|
663
663
|
# now, resolve all toctree nodes
|
|
664
664
|
for toctreenode in doctree.findall(addnodes.toctree):
|
|
665
665
|
result = toctree_adapters._resolve_toctree(
|
|
666
|
-
self,
|
|
666
|
+
self,
|
|
667
|
+
docname,
|
|
668
|
+
builder,
|
|
669
|
+
toctreenode,
|
|
667
670
|
prune=prune_toctrees,
|
|
668
671
|
includehidden=includehidden,
|
|
669
672
|
)
|
|
@@ -674,9 +677,17 @@ class BuildEnvironment:
|
|
|
674
677
|
|
|
675
678
|
return doctree
|
|
676
679
|
|
|
677
|
-
def resolve_toctree(
|
|
678
|
-
|
|
679
|
-
|
|
680
|
+
def resolve_toctree(
|
|
681
|
+
self,
|
|
682
|
+
docname: str,
|
|
683
|
+
builder: Builder,
|
|
684
|
+
toctree: addnodes.toctree,
|
|
685
|
+
prune: bool = True,
|
|
686
|
+
maxdepth: int = 0,
|
|
687
|
+
titles_only: bool = False,
|
|
688
|
+
collapse: bool = False,
|
|
689
|
+
includehidden: bool = False,
|
|
690
|
+
) -> Node | None:
|
|
680
691
|
"""Resolve a *toctree* node into individual bullet lists with titles
|
|
681
692
|
as items, returning None (if no containing titles are found) or
|
|
682
693
|
a new node.
|
|
@@ -689,7 +700,10 @@ class BuildEnvironment:
|
|
|
689
700
|
be collapsed.
|
|
690
701
|
"""
|
|
691
702
|
return toctree_adapters._resolve_toctree(
|
|
692
|
-
self,
|
|
703
|
+
self,
|
|
704
|
+
docname,
|
|
705
|
+
builder,
|
|
706
|
+
toctree,
|
|
693
707
|
prune=prune,
|
|
694
708
|
maxdepth=maxdepth,
|
|
695
709
|
titles_only=titles_only,
|
|
@@ -697,8 +711,9 @@ class BuildEnvironment:
|
|
|
697
711
|
includehidden=includehidden,
|
|
698
712
|
)
|
|
699
713
|
|
|
700
|
-
def resolve_references(
|
|
701
|
-
|
|
714
|
+
def resolve_references(
|
|
715
|
+
self, doctree: nodes.document, fromdocname: str, builder: Builder
|
|
716
|
+
) -> None:
|
|
702
717
|
self.apply_post_transforms(doctree, fromdocname)
|
|
703
718
|
|
|
704
719
|
def apply_post_transforms(self, doctree: nodes.document, docname: str) -> None:
|
|
@@ -723,7 +738,7 @@ class BuildEnvironment:
|
|
|
723
738
|
|
|
724
739
|
relations = {}
|
|
725
740
|
docnames = _traverse_toctree(
|
|
726
|
-
traversed, None, self.config.root_doc, self.toctree_includes
|
|
741
|
+
traversed, None, self.config.root_doc, self.toctree_includes
|
|
727
742
|
)
|
|
728
743
|
prev_doc = None
|
|
729
744
|
parent, docname = next(docnames)
|
|
@@ -750,15 +765,32 @@ class BuildEnvironment:
|
|
|
750
765
|
continue
|
|
751
766
|
if 'orphan' in self.metadata[docname]:
|
|
752
767
|
continue
|
|
753
|
-
logger.warning(
|
|
754
|
-
|
|
768
|
+
logger.warning(
|
|
769
|
+
__("document isn't included in any toctree"), location=docname
|
|
770
|
+
)
|
|
771
|
+
# Call _check_toc_parents here rather than in _get_toctree_ancestors()
|
|
772
|
+
# because that method is called multiple times per document and would
|
|
773
|
+
# lead to duplicate warnings.
|
|
774
|
+
_check_toc_parents(self.toctree_includes)
|
|
755
775
|
|
|
756
776
|
# call check-consistency for all extensions
|
|
757
|
-
|
|
758
|
-
domain.check_consistency()
|
|
777
|
+
self.domains._check_consistency()
|
|
759
778
|
self.events.emit('env-check-consistency', self)
|
|
760
779
|
|
|
761
780
|
|
|
781
|
+
def _differing_config_keys(old: Config, new: Config) -> frozenset[str]:
|
|
782
|
+
"""Return a set of keys that differ between two config objects."""
|
|
783
|
+
old_vals = {c.name: c.value for c in old}
|
|
784
|
+
new_vals = {c.name: c.value for c in new}
|
|
785
|
+
not_in_both = old_vals.keys() ^ new_vals.keys()
|
|
786
|
+
different_values = {
|
|
787
|
+
key
|
|
788
|
+
for key in old_vals.keys() & new_vals.keys()
|
|
789
|
+
if stable_str(old_vals[key]) != stable_str(new_vals[key])
|
|
790
|
+
}
|
|
791
|
+
return frozenset(not_in_both | different_values)
|
|
792
|
+
|
|
793
|
+
|
|
762
794
|
def _traverse_toctree(
|
|
763
795
|
traversed: set[str],
|
|
764
796
|
parent: str | None,
|
|
@@ -766,9 +798,12 @@ def _traverse_toctree(
|
|
|
766
798
|
toctree_includes: dict[str, list[str]],
|
|
767
799
|
) -> Iterator[tuple[str | None, str]]:
|
|
768
800
|
if parent == docname:
|
|
769
|
-
logger.warning(
|
|
770
|
-
|
|
771
|
-
|
|
801
|
+
logger.warning(
|
|
802
|
+
__('self referenced toctree found. Ignored.'),
|
|
803
|
+
location=docname,
|
|
804
|
+
type='toc',
|
|
805
|
+
subtype='circular',
|
|
806
|
+
)
|
|
772
807
|
return
|
|
773
808
|
|
|
774
809
|
# traverse toctree by pre-order
|
|
@@ -777,8 +812,29 @@ def _traverse_toctree(
|
|
|
777
812
|
|
|
778
813
|
for child in toctree_includes.get(docname, ()):
|
|
779
814
|
for sub_parent, sub_docname in _traverse_toctree(
|
|
780
|
-
traversed, docname, child, toctree_includes
|
|
815
|
+
traversed, docname, child, toctree_includes
|
|
781
816
|
):
|
|
782
817
|
if sub_docname not in traversed:
|
|
783
818
|
yield sub_parent, sub_docname
|
|
784
819
|
traversed.add(sub_docname)
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
def _check_toc_parents(toctree_includes: dict[str, list[str]]) -> None:
|
|
823
|
+
toc_parents: dict[str, list[str]] = {}
|
|
824
|
+
for parent, children in toctree_includes.items():
|
|
825
|
+
for child in children:
|
|
826
|
+
toc_parents.setdefault(child, []).append(parent)
|
|
827
|
+
|
|
828
|
+
for doc, parents in sorted(toc_parents.items()):
|
|
829
|
+
if len(parents) > 1:
|
|
830
|
+
logger.info(
|
|
831
|
+
__(
|
|
832
|
+
'document is referenced in multiple toctrees: %s, selecting: %s <- %s'
|
|
833
|
+
),
|
|
834
|
+
parents,
|
|
835
|
+
max(parents),
|
|
836
|
+
doc,
|
|
837
|
+
location=doc,
|
|
838
|
+
type='toc',
|
|
839
|
+
subtype='multiple_toc_parents',
|
|
840
|
+
)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Assets adapter for sphinx.environment."""
|
|
2
2
|
|
|
3
3
|
from sphinx.environment import BuildEnvironment
|
|
4
|
+
from sphinx.util._pathlib import _StrPath
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
class ImageAdapter:
|
|
@@ -9,7 +10,7 @@ class ImageAdapter:
|
|
|
9
10
|
|
|
10
11
|
def get_original_image_uri(self, name: str) -> str:
|
|
11
12
|
"""Get the original image URI."""
|
|
12
|
-
while name in self.env.original_image_uri:
|
|
13
|
-
name = self.env.original_image_uri[name]
|
|
13
|
+
while _StrPath(name) in self.env.original_image_uri:
|
|
14
|
+
name = self.env.original_image_uri[_StrPath(name)]
|
|
14
15
|
|
|
15
16
|
return name
|