Sphinx 8.0.2__py3-none-any.whl → 8.1.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.
- 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 +206 -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 +133 -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 +107 -39
- sphinx/texinputs/sphinxlatexadmonitions.sty +51 -35
- 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.0.dist-info/LICENSE.rst +31 -0
- {sphinx-8.0.2.dist-info → sphinx-8.1.0.dist-info}/METADATA +13 -11
- sphinx-8.1.0.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.0.dist-info}/WHEEL +0 -0
- {sphinx-8.0.2.dist-info → sphinx-8.1.0.dist-info}/entry_points.txt +0 -0
sphinx/util/nodes.py
CHANGED
|
@@ -35,7 +35,7 @@ explicit_title_re = re.compile(r'^(.+?)\s*(?<!\x00)<([^<]*?)>$', re.DOTALL)
|
|
|
35
35
|
caption_ref_re = explicit_title_re # b/w compat alias
|
|
36
36
|
|
|
37
37
|
|
|
38
|
-
N = TypeVar(
|
|
38
|
+
N = TypeVar('N', bound=Node)
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
class NodeMatcher(Generic[N]):
|
|
@@ -135,8 +135,11 @@ def apply_source_workaround(node: Element) -> None:
|
|
|
135
135
|
# * rawsource of term node will have: ``term text : classifier1 : classifier2``
|
|
136
136
|
# * rawsource of classifier node will be None
|
|
137
137
|
if isinstance(node, nodes.classifier) and not node.rawsource:
|
|
138
|
-
logger.debug(
|
|
139
|
-
|
|
138
|
+
logger.debug(
|
|
139
|
+
'[i18n] PATCH: %r to have source, line and rawsource: %s',
|
|
140
|
+
get_full_module_name(node),
|
|
141
|
+
repr_domxml(node),
|
|
142
|
+
)
|
|
140
143
|
definition_list_item = node.parent
|
|
141
144
|
node.source = definition_list_item.source
|
|
142
145
|
node.line = definition_list_item.line - 1 # type: ignore[operator]
|
|
@@ -145,24 +148,37 @@ def apply_source_workaround(node: Element) -> None:
|
|
|
145
148
|
# docutils-0.15 fills in rawsource attribute, but not in source.
|
|
146
149
|
node.source = node.parent.source
|
|
147
150
|
if isinstance(node, nodes.image) and node.source is None:
|
|
148
|
-
logger.debug(
|
|
149
|
-
|
|
151
|
+
logger.debug(
|
|
152
|
+
'[i18n] PATCH: %r to have source, line: %s',
|
|
153
|
+
get_full_module_name(node),
|
|
154
|
+
repr_domxml(node),
|
|
155
|
+
)
|
|
150
156
|
node.source, node.line = node.parent.source, node.parent.line
|
|
151
157
|
if isinstance(node, nodes.title) and node.source is None:
|
|
152
|
-
logger.debug(
|
|
153
|
-
|
|
158
|
+
logger.debug(
|
|
159
|
+
'[i18n] PATCH: %r to have source: %s',
|
|
160
|
+
get_full_module_name(node),
|
|
161
|
+
repr_domxml(node),
|
|
162
|
+
)
|
|
154
163
|
node.source, node.line = node.parent.source, node.parent.line
|
|
155
164
|
if isinstance(node, nodes.term):
|
|
156
|
-
logger.debug(
|
|
157
|
-
|
|
165
|
+
logger.debug(
|
|
166
|
+
'[i18n] PATCH: %r to have rawsource: %s',
|
|
167
|
+
get_full_module_name(node),
|
|
168
|
+
repr_domxml(node),
|
|
169
|
+
)
|
|
158
170
|
# strip classifier from rawsource of term
|
|
159
171
|
for classifier in reversed(list(node.parent.findall(nodes.classifier))):
|
|
160
|
-
node.rawsource = re.sub(
|
|
161
|
-
|
|
172
|
+
node.rawsource = re.sub(
|
|
173
|
+
r'\s*:\s*%s' % re.escape(classifier.astext()), '', node.rawsource
|
|
174
|
+
)
|
|
162
175
|
if isinstance(node, nodes.topic) and node.source is None:
|
|
163
176
|
# docutils-0.18 does not fill the source attribute of topic
|
|
164
|
-
logger.debug(
|
|
165
|
-
|
|
177
|
+
logger.debug(
|
|
178
|
+
'[i18n] PATCH: %r to have source, line: %s',
|
|
179
|
+
get_full_module_name(node),
|
|
180
|
+
repr_domxml(node),
|
|
181
|
+
)
|
|
166
182
|
node.source, node.line = node.parent.source, node.parent.line
|
|
167
183
|
|
|
168
184
|
# workaround: literal_block under bullet list (#4913)
|
|
@@ -178,14 +194,20 @@ def apply_source_workaround(node: Element) -> None:
|
|
|
178
194
|
return
|
|
179
195
|
|
|
180
196
|
# workaround: some docutils nodes doesn't have source, line.
|
|
181
|
-
if isinstance(
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
197
|
+
if isinstance(
|
|
198
|
+
node,
|
|
199
|
+
(
|
|
200
|
+
nodes.rubric # #1305 rubric directive
|
|
201
|
+
| nodes.line # #1477 line node
|
|
202
|
+
| nodes.image # #3093 image directive in substitution
|
|
203
|
+
| nodes.field_name # #3335 field list syntax
|
|
204
|
+
),
|
|
205
|
+
):
|
|
206
|
+
logger.debug(
|
|
207
|
+
'[i18n] PATCH: %r to have source and line: %s',
|
|
208
|
+
get_full_module_name(node),
|
|
209
|
+
repr_domxml(node),
|
|
210
|
+
)
|
|
189
211
|
try:
|
|
190
212
|
node.source = get_node_source(node)
|
|
191
213
|
except ValueError:
|
|
@@ -217,24 +239,36 @@ def is_translatable(node: Node) -> bool:
|
|
|
217
239
|
|
|
218
240
|
if isinstance(node, nodes.TextElement):
|
|
219
241
|
if not node.source:
|
|
220
|
-
logger.debug(
|
|
221
|
-
|
|
242
|
+
logger.debug(
|
|
243
|
+
'[i18n] SKIP %r because no node.source: %s',
|
|
244
|
+
get_full_module_name(node),
|
|
245
|
+
repr_domxml(node),
|
|
246
|
+
)
|
|
222
247
|
return False # built-in message
|
|
223
248
|
if isinstance(node, IGNORED_NODES) and 'translatable' not in node:
|
|
224
|
-
logger.debug(
|
|
225
|
-
|
|
226
|
-
|
|
249
|
+
logger.debug(
|
|
250
|
+
'[i18n] SKIP %r because node is in IGNORED_NODES '
|
|
251
|
+
"and no node['translatable']: %s",
|
|
252
|
+
get_full_module_name(node),
|
|
253
|
+
repr_domxml(node),
|
|
254
|
+
)
|
|
227
255
|
return False
|
|
228
256
|
if not node.get('translatable', True):
|
|
229
257
|
# not(node['translatable'] == True or node['translatable'] is None)
|
|
230
|
-
logger.debug(
|
|
231
|
-
|
|
258
|
+
logger.debug(
|
|
259
|
+
"[i18n] SKIP %r because not node['translatable']: %s",
|
|
260
|
+
get_full_module_name(node),
|
|
261
|
+
repr_domxml(node),
|
|
262
|
+
)
|
|
232
263
|
return False
|
|
233
264
|
# <field_name>orphan</field_name>
|
|
234
265
|
# XXX ignore all metadata (== docinfo)
|
|
235
266
|
if isinstance(node, nodes.field_name) and (node.children[0] == 'orphan'):
|
|
236
|
-
logger.debug(
|
|
237
|
-
|
|
267
|
+
logger.debug(
|
|
268
|
+
'[i18n] SKIP %r because orphan node: %s',
|
|
269
|
+
get_full_module_name(node),
|
|
270
|
+
repr_domxml(node),
|
|
271
|
+
)
|
|
238
272
|
return False
|
|
239
273
|
return True
|
|
240
274
|
|
|
@@ -249,7 +283,7 @@ LITERAL_TYPE_NODES = (
|
|
|
249
283
|
)
|
|
250
284
|
IMAGE_TYPE_NODES = (
|
|
251
285
|
nodes.image,
|
|
252
|
-
)
|
|
286
|
+
) # fmt: skip
|
|
253
287
|
|
|
254
288
|
|
|
255
289
|
def extract_messages(doctree: Element) -> Iterable[tuple[Element, str]]:
|
|
@@ -272,7 +306,7 @@ def extract_messages(doctree: Element) -> Iterable[tuple[Element, str]]:
|
|
|
272
306
|
else:
|
|
273
307
|
msg = ''
|
|
274
308
|
elif isinstance(node, nodes.meta):
|
|
275
|
-
msg = node[
|
|
309
|
+
msg = node['content']
|
|
276
310
|
else:
|
|
277
311
|
msg = node.rawsource.replace('\n', ' ').strip() # type: ignore[attr-defined]
|
|
278
312
|
|
|
@@ -325,8 +359,9 @@ def traverse_translatable_index(
|
|
|
325
359
|
yield node, entries
|
|
326
360
|
|
|
327
361
|
|
|
328
|
-
def nested_parse_with_titles(
|
|
329
|
-
|
|
362
|
+
def nested_parse_with_titles(
|
|
363
|
+
state: RSTState, content: StringList, node: Node, content_offset: int = 0
|
|
364
|
+
) -> str:
|
|
330
365
|
"""Version of state.nested_parse() that allows titles and does not require
|
|
331
366
|
titles to have the same decoration as the calling document.
|
|
332
367
|
|
|
@@ -359,13 +394,13 @@ def split_explicit_title(text: str) -> tuple[bool, str, str]:
|
|
|
359
394
|
return False, text, text
|
|
360
395
|
|
|
361
396
|
|
|
362
|
-
indextypes = [
|
|
363
|
-
'single', 'pair', 'double', 'triple', 'see', 'seealso',
|
|
364
|
-
]
|
|
397
|
+
indextypes = ['single', 'pair', 'double', 'triple', 'see', 'seealso']
|
|
365
398
|
|
|
366
399
|
|
|
367
|
-
def process_index_entry(
|
|
368
|
-
|
|
400
|
+
def process_index_entry(
|
|
401
|
+
entry: str,
|
|
402
|
+
targetid: str,
|
|
403
|
+
) -> list[tuple[str, str, str, str, str | None]]:
|
|
369
404
|
from sphinx.domains.python import pairindextypes
|
|
370
405
|
|
|
371
406
|
indexentries: list[tuple[str, str, str, str, str | None]] = []
|
|
@@ -377,18 +412,25 @@ def process_index_entry(entry: str, targetid: str,
|
|
|
377
412
|
entry = entry[1:].lstrip()
|
|
378
413
|
for index_type in pairindextypes:
|
|
379
414
|
if entry.startswith(f'{index_type}:'):
|
|
380
|
-
value = entry[len(index_type) + 1:].strip()
|
|
415
|
+
value = entry[len(index_type) + 1 :].strip()
|
|
381
416
|
value = f'{pairindextypes[index_type]}; {value}'
|
|
382
417
|
# xref RemovedInSphinx90Warning
|
|
383
|
-
logger.warning(
|
|
384
|
-
|
|
385
|
-
|
|
418
|
+
logger.warning(
|
|
419
|
+
__(
|
|
420
|
+
'%r is deprecated for index entries (from entry %r). '
|
|
421
|
+
"Use 'pair: %s' instead."
|
|
422
|
+
),
|
|
423
|
+
index_type,
|
|
424
|
+
entry,
|
|
425
|
+
value,
|
|
426
|
+
type='index',
|
|
427
|
+
)
|
|
386
428
|
indexentries.append(('pair', value, targetid, main, None))
|
|
387
429
|
break
|
|
388
430
|
else:
|
|
389
431
|
for index_type in indextypes:
|
|
390
432
|
if entry.startswith(f'{index_type}:'):
|
|
391
|
-
value = entry[len(index_type) + 1:].strip()
|
|
433
|
+
value = entry[len(index_type) + 1 :].strip()
|
|
392
434
|
if index_type == 'double':
|
|
393
435
|
index_type = 'pair'
|
|
394
436
|
indexentries.append((index_type, value, targetid, main, None))
|
|
@@ -414,6 +456,7 @@ def inline_all_toctrees(
|
|
|
414
456
|
tree: nodes.document,
|
|
415
457
|
colorfunc: Callable[[str], str],
|
|
416
458
|
traversed: list[str],
|
|
459
|
+
indent: str = '',
|
|
417
460
|
) -> nodes.document:
|
|
418
461
|
"""Inline all toctrees in the *tree*.
|
|
419
462
|
|
|
@@ -423,18 +466,28 @@ def inline_all_toctrees(
|
|
|
423
466
|
for toctreenode in list(tree.findall(addnodes.toctree)):
|
|
424
467
|
newnodes = []
|
|
425
468
|
includefiles = map(str, toctreenode['includefiles'])
|
|
469
|
+
indent += ' '
|
|
426
470
|
for includefile in includefiles:
|
|
427
471
|
if includefile not in traversed:
|
|
428
472
|
try:
|
|
429
473
|
traversed.append(includefile)
|
|
430
|
-
logger.info(colorfunc(includefile)
|
|
431
|
-
subtree = inline_all_toctrees(
|
|
432
|
-
|
|
433
|
-
|
|
474
|
+
logger.info(indent + colorfunc(includefile))
|
|
475
|
+
subtree = inline_all_toctrees(
|
|
476
|
+
builder,
|
|
477
|
+
docnameset,
|
|
478
|
+
includefile,
|
|
479
|
+
builder.env.get_doctree(includefile),
|
|
480
|
+
colorfunc,
|
|
481
|
+
traversed,
|
|
482
|
+
indent,
|
|
483
|
+
)
|
|
434
484
|
docnameset.add(includefile)
|
|
435
485
|
except Exception:
|
|
436
|
-
logger.warning(
|
|
437
|
-
|
|
486
|
+
logger.warning(
|
|
487
|
+
__('toctree contains ref to nonexisting file %r'),
|
|
488
|
+
includefile,
|
|
489
|
+
location=docname,
|
|
490
|
+
)
|
|
438
491
|
else:
|
|
439
492
|
sof = addnodes.start_of_file(docname=includefile)
|
|
440
493
|
sof.children = subtree.children
|
|
@@ -476,57 +529,61 @@ def _make_id(string: str) -> str:
|
|
|
476
529
|
_non_id_chars = re.compile('[^a-zA-Z0-9._]+')
|
|
477
530
|
_non_id_at_ends = re.compile('^[-0-9._]+|-+$')
|
|
478
531
|
_non_id_translate = {
|
|
479
|
-
|
|
480
|
-
0x0111: 'd',
|
|
481
|
-
0x0127: 'h',
|
|
482
|
-
0x0131: 'i',
|
|
483
|
-
0x0142: 'l',
|
|
484
|
-
0x0167: 't',
|
|
485
|
-
0x0180: 'b',
|
|
486
|
-
0x0183: 'b',
|
|
487
|
-
0x0188: 'c',
|
|
488
|
-
|
|
489
|
-
0x0192: 'f',
|
|
490
|
-
0x0199: 'k',
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
0x0225: 'z',
|
|
500
|
-
0x0234: 'l',
|
|
501
|
-
0x0235: 'n',
|
|
502
|
-
0x0236: 't',
|
|
503
|
-
0x0237: 'j',
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
0x0240: 'z',
|
|
507
|
-
0x0247: 'e',
|
|
508
|
-
0x0249: 'j',
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
532
|
+
0x00F8: 'o', # o with stroke
|
|
533
|
+
0x0111: 'd', # d with stroke
|
|
534
|
+
0x0127: 'h', # h with stroke
|
|
535
|
+
0x0131: 'i', # dotless i
|
|
536
|
+
0x0142: 'l', # l with stroke
|
|
537
|
+
0x0167: 't', # t with stroke
|
|
538
|
+
0x0180: 'b', # b with stroke
|
|
539
|
+
0x0183: 'b', # b with topbar
|
|
540
|
+
0x0188: 'c', # c with hook
|
|
541
|
+
0x018C: 'd', # d with topbar
|
|
542
|
+
0x0192: 'f', # f with hook
|
|
543
|
+
0x0199: 'k', # k with hook
|
|
544
|
+
0x019A: 'l', # l with bar
|
|
545
|
+
0x019E: 'n', # n with long right leg
|
|
546
|
+
0x01A5: 'p', # p with hook
|
|
547
|
+
0x01AB: 't', # t with palatal hook
|
|
548
|
+
0x01AD: 't', # t with hook
|
|
549
|
+
0x01B4: 'y', # y with hook
|
|
550
|
+
0x01B6: 'z', # z with stroke
|
|
551
|
+
0x01E5: 'g', # g with stroke
|
|
552
|
+
0x0225: 'z', # z with hook
|
|
553
|
+
0x0234: 'l', # l with curl
|
|
554
|
+
0x0235: 'n', # n with curl
|
|
555
|
+
0x0236: 't', # t with curl
|
|
556
|
+
0x0237: 'j', # dotless j
|
|
557
|
+
0x023C: 'c', # c with stroke
|
|
558
|
+
0x023F: 's', # s with swash tail
|
|
559
|
+
0x0240: 'z', # z with swash tail
|
|
560
|
+
0x0247: 'e', # e with stroke
|
|
561
|
+
0x0249: 'j', # j with stroke
|
|
562
|
+
0x024B: 'q', # q with hook tail
|
|
563
|
+
0x024D: 'r', # r with stroke
|
|
564
|
+
0x024F: 'y', # y with stroke
|
|
512
565
|
}
|
|
513
566
|
_non_id_translate_digraphs = {
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
0x0153: 'oe',
|
|
517
|
-
0x0238: 'db',
|
|
518
|
-
0x0239: 'qp',
|
|
567
|
+
0x00DF: 'sz', # ligature sz
|
|
568
|
+
0x00E6: 'ae', # ae
|
|
569
|
+
0x0153: 'oe', # ligature oe
|
|
570
|
+
0x0238: 'db', # db digraph
|
|
571
|
+
0x0239: 'qp', # qp digraph
|
|
519
572
|
}
|
|
520
573
|
|
|
521
574
|
|
|
522
|
-
def make_id(
|
|
523
|
-
|
|
575
|
+
def make_id(
|
|
576
|
+
env: BuildEnvironment,
|
|
577
|
+
document: nodes.document,
|
|
578
|
+
prefix: str = '',
|
|
579
|
+
term: str | None = None,
|
|
580
|
+
) -> str:
|
|
524
581
|
"""Generate an appropriate node_id for given *prefix* and *term*."""
|
|
525
582
|
node_id = None
|
|
526
583
|
if prefix:
|
|
527
|
-
idformat = prefix +
|
|
584
|
+
idformat = prefix + '-%s'
|
|
528
585
|
else:
|
|
529
|
-
idformat = (document.settings.id_prefix or
|
|
586
|
+
idformat = (document.settings.id_prefix or 'id') + '%s'
|
|
530
587
|
|
|
531
588
|
# try to generate node_id by *term*
|
|
532
589
|
if prefix and term:
|
|
@@ -545,27 +602,36 @@ def make_id(env: BuildEnvironment, document: nodes.document,
|
|
|
545
602
|
return node_id
|
|
546
603
|
|
|
547
604
|
|
|
548
|
-
def find_pending_xref_condition(
|
|
549
|
-
|
|
605
|
+
def find_pending_xref_condition(
|
|
606
|
+
node: addnodes.pending_xref, condition: str
|
|
607
|
+
) -> Element | None:
|
|
550
608
|
"""Pick matched pending_xref_condition node up from the pending_xref."""
|
|
551
609
|
for subnode in node:
|
|
552
|
-
if (
|
|
553
|
-
|
|
610
|
+
if (
|
|
611
|
+
isinstance(subnode, addnodes.pending_xref_condition)
|
|
612
|
+
and subnode.get('condition') == condition
|
|
613
|
+
):
|
|
554
614
|
return subnode
|
|
555
615
|
return None
|
|
556
616
|
|
|
557
617
|
|
|
558
|
-
def make_refnode(
|
|
559
|
-
|
|
560
|
-
|
|
618
|
+
def make_refnode(
|
|
619
|
+
builder: Builder,
|
|
620
|
+
fromdocname: str,
|
|
621
|
+
todocname: str,
|
|
622
|
+
targetid: str | None,
|
|
623
|
+
child: Node | list[Node],
|
|
624
|
+
title: str | None = None,
|
|
625
|
+
) -> nodes.reference:
|
|
561
626
|
"""Shortcut to create a reference node."""
|
|
562
627
|
node = nodes.reference('', '', internal=True)
|
|
563
628
|
if fromdocname == todocname and targetid:
|
|
564
629
|
node['refid'] = targetid
|
|
565
630
|
else:
|
|
566
631
|
if targetid:
|
|
567
|
-
node['refuri'] = (
|
|
568
|
-
|
|
632
|
+
node['refuri'] = (
|
|
633
|
+
builder.get_relative_uri(fromdocname, todocname) + '#' + targetid
|
|
634
|
+
)
|
|
569
635
|
else:
|
|
570
636
|
node['refuri'] = builder.get_relative_uri(fromdocname, todocname)
|
|
571
637
|
if title:
|
|
@@ -575,8 +641,9 @@ def make_refnode(builder: Builder, fromdocname: str, todocname: str, targetid: s
|
|
|
575
641
|
|
|
576
642
|
|
|
577
643
|
def set_source_info(directive: Directive, node: Node) -> None:
|
|
578
|
-
node.source, node.line =
|
|
579
|
-
directive.
|
|
644
|
+
node.source, node.line = directive.state_machine.get_source_and_line(
|
|
645
|
+
directive.lineno
|
|
646
|
+
)
|
|
580
647
|
|
|
581
648
|
|
|
582
649
|
def set_role_source_info(inliner: Inliner, lineno: int, node: Node) -> None:
|
|
@@ -633,7 +700,8 @@ def _only_node_keep_children(node: addnodes.only, tags: Tags) -> bool:
|
|
|
633
700
|
logger.warning(
|
|
634
701
|
__('exception while evaluating only directive expression: %s'),
|
|
635
702
|
err,
|
|
636
|
-
location=node
|
|
703
|
+
location=node,
|
|
704
|
+
)
|
|
637
705
|
return True
|
|
638
706
|
|
|
639
707
|
|
|
@@ -649,10 +717,10 @@ def _copy_except__document(el: Element) -> Element:
|
|
|
649
717
|
newnode.rawsource = el.rawsource
|
|
650
718
|
newnode.tagname = el.tagname
|
|
651
719
|
# copied in Element.copy()
|
|
652
|
-
newnode.attributes = {
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
720
|
+
newnode.attributes = {
|
|
721
|
+
k: (v if k not in {'ids', 'classes', 'names', 'dupnames', 'backrefs'} else v[:])
|
|
722
|
+
for k, v in el.attributes.items()
|
|
723
|
+
}
|
|
656
724
|
newnode.line = el.line
|
|
657
725
|
newnode.source = el.source
|
|
658
726
|
return newnode
|
sphinx/util/osutil.py
CHANGED
|
@@ -25,7 +25,7 @@ if TYPE_CHECKING:
|
|
|
25
25
|
# Define SEP as a manifest constant, not so much because we expect it to change
|
|
26
26
|
# in the future as to avoid the suspicion that a stray "/" in the code is a
|
|
27
27
|
# hangover from more *nix-oriented origins.
|
|
28
|
-
SEP =
|
|
28
|
+
SEP = '/'
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
def os_path(canonical_path: str, /) -> str:
|
|
@@ -115,21 +115,23 @@ def copyfile(
|
|
|
115
115
|
raise FileNotFoundError(msg)
|
|
116
116
|
|
|
117
117
|
if (
|
|
118
|
-
not (dest_exists := dest.exists())
|
|
118
|
+
not (dest_exists := dest.exists())
|
|
119
119
|
# comparison must be done using shallow=False since
|
|
120
120
|
# two different files might have the same size
|
|
121
|
-
not filecmp.cmp(source, dest, shallow=False)
|
|
121
|
+
or not filecmp.cmp(source, dest, shallow=False)
|
|
122
122
|
):
|
|
123
123
|
if not force and dest_exists:
|
|
124
124
|
# sphinx.util.logging imports sphinx.util.osutil,
|
|
125
125
|
# so use a local import to avoid circular imports
|
|
126
126
|
from sphinx.util import logging
|
|
127
|
+
|
|
127
128
|
logger = logging.getLogger(__name__)
|
|
128
129
|
|
|
129
|
-
msg = __(
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
130
|
+
msg = __(
|
|
131
|
+
'Aborted attempted copy from %s to %s '
|
|
132
|
+
'(the destination path has existing data).'
|
|
133
|
+
)
|
|
134
|
+
logger.warning(msg, source, dest, type='misc', subtype='copy_overwrite')
|
|
133
135
|
return
|
|
134
136
|
|
|
135
137
|
shutil.copyfile(source, dest)
|
|
@@ -149,8 +151,9 @@ def make_filename_from_project(project: str) -> str:
|
|
|
149
151
|
return make_filename(project.removesuffix(' Documentation')).lower()
|
|
150
152
|
|
|
151
153
|
|
|
152
|
-
def relpath(
|
|
153
|
-
|
|
154
|
+
def relpath(
|
|
155
|
+
path: str | os.PathLike[str], start: str | os.PathLike[str] | None = os.curdir
|
|
156
|
+
) -> str:
|
|
154
157
|
"""Return a relative filepath to *path* either from the current directory or
|
|
155
158
|
from an optional *start* directory.
|
|
156
159
|
|
|
@@ -241,7 +244,7 @@ class FileAvoidWrite:
|
|
|
241
244
|
return self
|
|
242
245
|
|
|
243
246
|
def __exit__(
|
|
244
|
-
self, exc_type: type[Exception], exc_value: Exception, traceback: Any
|
|
247
|
+
self, exc_type: type[Exception], exc_value: Exception, traceback: Any
|
|
245
248
|
) -> bool:
|
|
246
249
|
self.close()
|
|
247
250
|
return True
|
sphinx/util/parallel.py
CHANGED
|
@@ -10,6 +10,7 @@ from typing import TYPE_CHECKING, Any
|
|
|
10
10
|
|
|
11
11
|
try:
|
|
12
12
|
import multiprocessing
|
|
13
|
+
|
|
13
14
|
HAS_MULTIPROCESSING = True
|
|
14
15
|
except ImportError:
|
|
15
16
|
HAS_MULTIPROCESSING = False
|
|
@@ -23,7 +24,7 @@ if TYPE_CHECKING:
|
|
|
23
24
|
logger = logging.getLogger(__name__)
|
|
24
25
|
|
|
25
26
|
# our parallel functionality only works for the forking Process
|
|
26
|
-
parallel_available =
|
|
27
|
+
parallel_available = HAS_MULTIPROCESSING and os.name == 'posix'
|
|
27
28
|
|
|
28
29
|
|
|
29
30
|
class SerialTasks:
|
|
@@ -33,7 +34,7 @@ class SerialTasks:
|
|
|
33
34
|
pass
|
|
34
35
|
|
|
35
36
|
def add_task(
|
|
36
|
-
self, task_func: Callable, arg: Any = None, result_func: Callable | None = None
|
|
37
|
+
self, task_func: Callable, arg: Any = None, result_func: Callable | None = None
|
|
37
38
|
) -> None:
|
|
38
39
|
if arg is not None:
|
|
39
40
|
res = task_func(arg)
|
|
@@ -83,7 +84,7 @@ class ParallelTasks:
|
|
|
83
84
|
pipe.send((failed, collector.logs, ret))
|
|
84
85
|
|
|
85
86
|
def add_task(
|
|
86
|
-
self, task_func: Callable, arg: Any = None, result_func: Callable | None = None
|
|
87
|
+
self, task_func: Callable, arg: Any = None, result_func: Callable | None = None
|
|
87
88
|
) -> None:
|
|
88
89
|
tid = self._taskid
|
|
89
90
|
self._taskid += 1
|
|
@@ -156,4 +157,4 @@ def make_chunks(arguments: Sequence[str], nproc: int, maxbatch: int = 10) -> lis
|
|
|
156
157
|
if rest:
|
|
157
158
|
nchunks += 1
|
|
158
159
|
# partition documents in "chunks" that will be written by one Process
|
|
159
|
-
return [arguments[i * chunksize:(i + 1) * chunksize] for i in range(nchunks)]
|
|
160
|
+
return [arguments[i * chunksize : (i + 1) * chunksize] for i in range(nchunks)]
|
sphinx/util/parsing.py
CHANGED
|
@@ -53,7 +53,7 @@ def nested_parse_to_nodes(
|
|
|
53
53
|
"""
|
|
54
54
|
document = state.document
|
|
55
55
|
content = _text_to_string_list(
|
|
56
|
-
text, source=source, tab_width=document.settings.tab_width
|
|
56
|
+
text, source=source, tab_width=document.settings.tab_width
|
|
57
57
|
)
|
|
58
58
|
node = Element() # Anonymous container for parsing
|
|
59
59
|
node.document = document
|
|
@@ -62,7 +62,9 @@ def nested_parse_to_nodes(
|
|
|
62
62
|
state.nested_parse(content, offset, node, match_titles=allow_section_headings)
|
|
63
63
|
else:
|
|
64
64
|
with _fresh_title_style_context(state):
|
|
65
|
-
state.nested_parse(
|
|
65
|
+
state.nested_parse(
|
|
66
|
+
content, offset, node, match_titles=allow_section_headings
|
|
67
|
+
)
|
|
66
68
|
return node.children
|
|
67
69
|
|
|
68
70
|
|
|
@@ -84,7 +86,7 @@ def _fresh_title_style_context(state: RSTState) -> Iterator[None]:
|
|
|
84
86
|
|
|
85
87
|
|
|
86
88
|
def _text_to_string_list(
|
|
87
|
-
text: str | StringList, /, *, source: str, tab_width: int
|
|
89
|
+
text: str | StringList, /, *, source: str, tab_width: int
|
|
88
90
|
) -> StringList:
|
|
89
91
|
# Doesn't really belong in this module, but avoids circular imports.
|
|
90
92
|
if isinstance(text, StringList):
|
sphinx/util/png.py
CHANGED
|
@@ -10,13 +10,13 @@ LEN_DEPTH = 22
|
|
|
10
10
|
|
|
11
11
|
DEPTH_CHUNK_LEN = struct.pack('!i', 10)
|
|
12
12
|
DEPTH_CHUNK_START = b'tEXtDepth\x00'
|
|
13
|
-
IEND_CHUNK = b'\x00\x00\x00\x00IEND\
|
|
13
|
+
IEND_CHUNK = b'\x00\x00\x00\x00IEND\xae\x42\x60\x82'
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
def read_png_depth(filename: str) -> int | None:
|
|
17
17
|
"""Read the special tEXt chunk indicating the depth from a PNG file."""
|
|
18
18
|
with open(filename, 'rb') as f:
|
|
19
|
-
f.seek(-
|
|
19
|
+
f.seek(-(LEN_IEND + LEN_DEPTH), 2)
|
|
20
20
|
depthchunk = f.read(LEN_DEPTH)
|
|
21
21
|
if not depthchunk.startswith(DEPTH_CHUNK_LEN + DEPTH_CHUNK_START):
|
|
22
22
|
# either not a PNG file or not containing the depth chunk
|
|
@@ -37,7 +37,7 @@ def write_png_depth(filename: str, depth: int) -> None:
|
|
|
37
37
|
# overwrite it with the depth chunk
|
|
38
38
|
f.write(DEPTH_CHUNK_LEN + DEPTH_CHUNK_START + data)
|
|
39
39
|
# calculate the checksum over chunk name and data
|
|
40
|
-
crc = binascii.crc32(DEPTH_CHUNK_START + data) &
|
|
40
|
+
crc = binascii.crc32(DEPTH_CHUNK_START + data) & 0xFFFFFFFF
|
|
41
41
|
f.write(struct.pack('!I', crc))
|
|
42
42
|
# replace the IEND chunk
|
|
43
43
|
f.write(IEND_CHUNK)
|
sphinx/util/requests.py
CHANGED
|
@@ -11,8 +11,10 @@ from urllib3.exceptions import InsecureRequestWarning
|
|
|
11
11
|
|
|
12
12
|
import sphinx
|
|
13
13
|
|
|
14
|
-
_USER_AGENT = (
|
|
15
|
-
|
|
14
|
+
_USER_AGENT = (
|
|
15
|
+
f'Mozilla/5.0 (X11; Linux x86_64; rv:100.0) Gecko/20100101 Firefox/100.0 '
|
|
16
|
+
f'Sphinx/{sphinx.__version__}'
|
|
17
|
+
)
|
|
16
18
|
|
|
17
19
|
|
|
18
20
|
def _get_tls_cacert(url: str, certs: str | dict[str, str] | None) -> str | bool:
|
|
@@ -49,7 +51,9 @@ def head(url: str, **kwargs: Any) -> requests.Response:
|
|
|
49
51
|
|
|
50
52
|
class _Session(requests.Session):
|
|
51
53
|
def request( # type: ignore[override]
|
|
52
|
-
self,
|
|
54
|
+
self,
|
|
55
|
+
method: str,
|
|
56
|
+
url: str,
|
|
53
57
|
_user_agent: str = '',
|
|
54
58
|
_tls_info: tuple[bool, str | dict[str, str] | None] = (), # type: ignore[assignment]
|
|
55
59
|
**kwargs: Any,
|
|
@@ -72,5 +76,5 @@ class _Session(requests.Session):
|
|
|
72
76
|
|
|
73
77
|
with warnings.catch_warnings():
|
|
74
78
|
# ignore InsecureRequestWarning if verify=False
|
|
75
|
-
warnings.filterwarnings(
|
|
79
|
+
warnings.filterwarnings('ignore', category=InsecureRequestWarning)
|
|
76
80
|
return super().request(method, url, **kwargs)
|
sphinx/util/rst.py
CHANGED
|
@@ -29,8 +29,8 @@ symbols_re = re.compile(r'([!-\-/:-@\[-`{-~])') # symbols without dot(0x2e)
|
|
|
29
29
|
SECTIONING_CHARS = ['=', '-', '~']
|
|
30
30
|
|
|
31
31
|
# width of characters
|
|
32
|
-
WIDECHARS: dict[str, str] = defaultdict(lambda:
|
|
33
|
-
WIDECHARS[
|
|
32
|
+
WIDECHARS: dict[str, str] = defaultdict(lambda: 'WF') # WF: Wide + Full-width
|
|
33
|
+
WIDECHARS['ja'] = 'WFA' # In Japanese, Ambiguous characters also have double width
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
def escape(text: str) -> str:
|
|
@@ -41,6 +41,7 @@ def escape(text: str) -> str:
|
|
|
41
41
|
|
|
42
42
|
def textwidth(text: str, widechars: str = 'WF') -> int:
|
|
43
43
|
"""Get width of text."""
|
|
44
|
+
|
|
44
45
|
def charwidth(char: str, widechars: str) -> int:
|
|
45
46
|
if east_asian_width(char) in widechars:
|
|
46
47
|
return 2
|
|
@@ -103,7 +104,8 @@ def append_epilog(content: StringList, epilog: str) -> None:
|
|
|
103
104
|
if epilog:
|
|
104
105
|
if len(content) > 0:
|
|
105
106
|
source, lineno = content.info(-1)
|
|
106
|
-
|
|
107
|
+
# lineno will never be None, since len(content) > 0
|
|
108
|
+
lineno = cast(int, lineno)
|
|
107
109
|
else:
|
|
108
110
|
source = '<generated>'
|
|
109
111
|
lineno = 0
|