Sphinx 7.2.6__py3-none-any.whl → 7.3.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 +8 -9
- sphinx/addnodes.py +31 -28
- sphinx/application.py +9 -15
- sphinx/builders/__init__.py +5 -6
- sphinx/builders/_epub_base.py +17 -9
- sphinx/builders/changes.py +10 -5
- sphinx/builders/dirhtml.py +4 -2
- sphinx/builders/dummy.py +3 -2
- sphinx/builders/epub3.py +5 -3
- sphinx/builders/gettext.py +24 -7
- sphinx/builders/html/__init__.py +88 -96
- sphinx/builders/html/_assets.py +16 -16
- sphinx/builders/html/transforms.py +4 -2
- sphinx/builders/latex/__init__.py +40 -33
- sphinx/builders/latex/nodes.py +6 -2
- sphinx/builders/latex/transforms.py +17 -8
- sphinx/builders/latex/util.py +1 -1
- sphinx/builders/linkcheck.py +86 -27
- sphinx/builders/manpage.py +8 -6
- sphinx/builders/singlehtml.py +5 -4
- sphinx/builders/texinfo.py +18 -14
- sphinx/builders/text.py +3 -2
- sphinx/builders/xml.py +5 -2
- sphinx/cmd/build.py +119 -76
- sphinx/cmd/make_mode.py +4 -9
- sphinx/cmd/quickstart.py +13 -16
- sphinx/config.py +432 -250
- sphinx/deprecation.py +23 -13
- sphinx/directives/__init__.py +8 -8
- sphinx/directives/code.py +7 -7
- sphinx/directives/other.py +23 -13
- sphinx/directives/patches.py +7 -6
- sphinx/domains/__init__.py +2 -2
- sphinx/domains/c/__init__.py +796 -0
- sphinx/domains/c/_ast.py +1421 -0
- sphinx/domains/c/_ids.py +65 -0
- sphinx/domains/c/_parser.py +1048 -0
- sphinx/domains/c/_symbol.py +700 -0
- sphinx/domains/changeset.py +11 -7
- sphinx/domains/citation.py +5 -2
- sphinx/domains/cpp/__init__.py +1089 -0
- sphinx/domains/cpp/_ast.py +3635 -0
- sphinx/domains/cpp/_ids.py +537 -0
- sphinx/domains/cpp/_parser.py +2117 -0
- sphinx/domains/cpp/_symbol.py +1092 -0
- sphinx/domains/index.py +6 -4
- sphinx/domains/javascript.py +16 -13
- sphinx/domains/math.py +9 -4
- sphinx/domains/python/__init__.py +890 -0
- sphinx/domains/python/_annotations.py +507 -0
- sphinx/domains/python/_object.py +426 -0
- sphinx/domains/rst.py +12 -7
- sphinx/domains/{std.py → std/__init__.py} +19 -16
- sphinx/environment/__init__.py +21 -19
- sphinx/environment/adapters/indexentries.py +2 -2
- sphinx/environment/adapters/toctree.py +10 -9
- sphinx/environment/collectors/__init__.py +6 -3
- sphinx/environment/collectors/asset.py +4 -3
- sphinx/environment/collectors/dependencies.py +3 -2
- sphinx/environment/collectors/metadata.py +6 -5
- sphinx/environment/collectors/title.py +3 -2
- sphinx/environment/collectors/toctree.py +5 -4
- sphinx/errors.py +13 -2
- sphinx/events.py +14 -9
- sphinx/ext/apidoc.py +9 -11
- sphinx/ext/autodoc/__init__.py +105 -71
- sphinx/ext/autodoc/directive.py +7 -6
- sphinx/ext/autodoc/importer.py +102 -36
- sphinx/ext/autodoc/mock.py +7 -5
- sphinx/ext/autodoc/preserve_defaults.py +4 -3
- sphinx/ext/autodoc/type_comment.py +2 -1
- sphinx/ext/autodoc/typehints.py +5 -4
- sphinx/ext/autosectionlabel.py +3 -2
- sphinx/ext/autosummary/__init__.py +21 -17
- sphinx/ext/autosummary/generate.py +9 -9
- sphinx/ext/coverage.py +26 -20
- sphinx/ext/doctest.py +38 -33
- sphinx/ext/duration.py +1 -0
- sphinx/ext/extlinks.py +4 -3
- sphinx/ext/githubpages.py +3 -2
- sphinx/ext/graphviz.py +10 -7
- sphinx/ext/ifconfig.py +5 -5
- sphinx/ext/imgconverter.py +6 -5
- sphinx/ext/imgmath.py +9 -8
- sphinx/ext/inheritance_diagram.py +31 -31
- sphinx/ext/intersphinx.py +140 -23
- sphinx/ext/linkcode.py +3 -2
- sphinx/ext/mathjax.py +2 -1
- sphinx/ext/napoleon/__init__.py +12 -7
- sphinx/ext/napoleon/docstring.py +34 -32
- sphinx/ext/todo.py +10 -7
- sphinx/ext/viewcode.py +12 -11
- sphinx/extension.py +18 -8
- sphinx/highlighting.py +39 -20
- sphinx/io.py +17 -8
- sphinx/jinja2glue.py +16 -15
- sphinx/locale/__init__.py +30 -23
- sphinx/locale/ar/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ar/LC_MESSAGES/sphinx.po +818 -761
- sphinx/locale/bg/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/bg/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/bn/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/bn/LC_MESSAGES/sphinx.po +835 -778
- sphinx/locale/ca/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ca/LC_MESSAGES/sphinx.po +864 -807
- sphinx/locale/cak/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cak/LC_MESSAGES/sphinx.po +816 -759
- sphinx/locale/cs/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cs/LC_MESSAGES/sphinx.po +837 -780
- sphinx/locale/cy/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cy/LC_MESSAGES/sphinx.po +819 -762
- sphinx/locale/da/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/da/LC_MESSAGES/sphinx.po +838 -781
- sphinx/locale/de/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/de/LC_MESSAGES/sphinx.po +838 -781
- sphinx/locale/de_DE/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/de_DE/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/el/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/el/LC_MESSAGES/sphinx.po +853 -796
- sphinx/locale/en_DE/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_DE/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/en_FR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_FR/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/en_GB/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_GB/LC_MESSAGES/sphinx.po +856 -799
- sphinx/locale/en_HK/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_HK/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/eo/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/eo/LC_MESSAGES/sphinx.po +820 -763
- sphinx/locale/es/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/es/LC_MESSAGES/sphinx.po +856 -799
- sphinx/locale/es_CO/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/es_CO/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/et/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/et/LC_MESSAGES/sphinx.po +845 -788
- sphinx/locale/eu/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/eu/LC_MESSAGES/sphinx.po +837 -780
- sphinx/locale/fa/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fa/LC_MESSAGES/sphinx.po +854 -797
- sphinx/locale/fi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fi/LC_MESSAGES/sphinx.po +816 -759
- sphinx/locale/fr/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/fr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fr/LC_MESSAGES/sphinx.po +904 -847
- sphinx/locale/fr_FR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fr_FR/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/gl/LC_MESSAGES/sphinx.js +54 -54
- sphinx/locale/gl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/gl/LC_MESSAGES/sphinx.po +1506 -1449
- sphinx/locale/he/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/he/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/he/LC_MESSAGES/sphinx.po +823 -766
- sphinx/locale/hi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hi/LC_MESSAGES/sphinx.po +853 -796
- sphinx/locale/hi_IN/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hi_IN/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/hr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hr/LC_MESSAGES/sphinx.po +844 -787
- sphinx/locale/hu/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hu/LC_MESSAGES/sphinx.po +837 -780
- sphinx/locale/id/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/id/LC_MESSAGES/sphinx.po +854 -797
- sphinx/locale/is/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/is/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/it/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/it/LC_MESSAGES/sphinx.po +837 -780
- sphinx/locale/ja/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ja/LC_MESSAGES/sphinx.po +853 -796
- sphinx/locale/ka/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ka/LC_MESSAGES/sphinx.po +848 -791
- sphinx/locale/ko/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ko/LC_MESSAGES/sphinx.po +855 -798
- sphinx/locale/lt/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/lt/LC_MESSAGES/sphinx.po +837 -780
- sphinx/locale/lv/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/lv/LC_MESSAGES/sphinx.po +837 -780
- sphinx/locale/mk/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/mk/LC_MESSAGES/sphinx.po +825 -768
- sphinx/locale/nb_NO/LC_MESSAGES/sphinx.js +27 -27
- sphinx/locale/nb_NO/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po +876 -818
- sphinx/locale/ne/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ne/LC_MESSAGES/sphinx.po +837 -780
- sphinx/locale/nl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/nl/LC_MESSAGES/sphinx.po +844 -787
- sphinx/locale/pl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pl/LC_MESSAGES/sphinx.po +845 -788
- sphinx/locale/pt/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po +908 -851
- sphinx/locale/pt_PT/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt_PT/LC_MESSAGES/sphinx.po +837 -780
- sphinx/locale/ro/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ro/LC_MESSAGES/sphinx.po +837 -780
- sphinx/locale/ru/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ru/LC_MESSAGES/sphinx.po +838 -781
- sphinx/locale/si/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/si/LC_MESSAGES/sphinx.po +823 -766
- sphinx/locale/sk/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sk/LC_MESSAGES/sphinx.po +854 -797
- sphinx/locale/sl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sl/LC_MESSAGES/sphinx.po +832 -775
- sphinx/locale/sphinx.pot +813 -755
- sphinx/locale/sq/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/sq/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sq/LC_MESSAGES/sphinx.po +865 -808
- sphinx/locale/sr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sr/LC_MESSAGES/sphinx.po +835 -778
- 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.mo +0 -0
- sphinx/locale/sv/LC_MESSAGES/sphinx.po +837 -780
- sphinx/locale/ta/LC_MESSAGES/sphinx.js +54 -54
- sphinx/locale/ta/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ta/LC_MESSAGES/sphinx.po +1530 -1473
- sphinx/locale/te/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/te/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/tr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/tr/LC_MESSAGES/sphinx.po +853 -796
- sphinx/locale/uk_UA/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po +833 -776
- sphinx/locale/ur/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ur/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/vi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/vi/LC_MESSAGES/sphinx.po +837 -780
- sphinx/locale/yue/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/yue/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/zh_CN/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_CN/LC_MESSAGES/sphinx.po +855 -798
- sphinx/locale/zh_HK/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_HK/LC_MESSAGES/sphinx.po +811 -754
- sphinx/locale/zh_TW/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/zh_TW/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po +879 -822
- sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.po +811 -754
- sphinx/parsers.py +7 -5
- sphinx/project.py +18 -11
- sphinx/pycode/__init__.py +6 -5
- sphinx/pycode/ast.py +23 -8
- sphinx/pycode/parser.py +6 -5
- sphinx/registry.py +12 -6
- sphinx/roles.py +103 -57
- sphinx/search/__init__.py +17 -18
- sphinx/search/da.py +2 -2
- sphinx/search/de.py +2 -2
- sphinx/search/en.py +1 -1
- sphinx/search/es.py +2 -2
- sphinx/search/fi.py +2 -2
- sphinx/search/fr.py +2 -2
- sphinx/search/hu.py +2 -2
- sphinx/search/it.py +2 -2
- sphinx/search/ja.py +13 -22
- sphinx/search/nl.py +2 -2
- sphinx/search/no.py +2 -2
- sphinx/search/pt.py +2 -2
- sphinx/search/ro.py +1 -1
- sphinx/search/ru.py +2 -2
- sphinx/search/sv.py +2 -2
- sphinx/search/tr.py +1 -1
- sphinx/search/zh.py +2 -3
- sphinx/templates/graphviz/graphviz.css +1 -1
- sphinx/testing/fixtures.py +41 -24
- sphinx/testing/path.py +1 -1
- sphinx/testing/util.py +142 -53
- sphinx/texinputs/sphinx.xdy +1 -1
- sphinx/texinputs/sphinxlatextables.sty +1 -1
- sphinx/texinputs/sphinxpackagesubstitutefont.sty +21 -0
- sphinx/themes/agogo/layout.html +4 -4
- sphinx/themes/agogo/static/agogo.css_t +1 -1
- sphinx/themes/agogo/theme.toml +22 -0
- sphinx/themes/basic/defindex.html +1 -1
- sphinx/themes/basic/domainindex.html +1 -1
- sphinx/themes/basic/genindex-single.html +1 -1
- sphinx/themes/basic/genindex-split.html +1 -1
- sphinx/themes/basic/genindex.html +1 -1
- sphinx/themes/basic/globaltoc.html +1 -1
- sphinx/themes/basic/layout.html +1 -1
- sphinx/themes/basic/localtoc.html +1 -1
- sphinx/themes/basic/page.html +1 -1
- sphinx/themes/basic/relations.html +1 -1
- sphinx/themes/basic/search.html +5 -20
- sphinx/themes/basic/searchbox.html +3 -3
- sphinx/themes/basic/searchfield.html +3 -3
- sphinx/themes/basic/sourcelink.html +1 -1
- sphinx/themes/basic/static/basic.css_t +1 -1
- sphinx/themes/basic/static/doctools.js +1 -1
- sphinx/themes/basic/static/language_data.js_t +2 -2
- sphinx/themes/basic/static/searchtools.js +105 -60
- sphinx/themes/basic/theme.toml +23 -0
- sphinx/themes/bizstyle/layout.html +1 -6
- sphinx/themes/bizstyle/static/bizstyle.css_t +1 -1
- sphinx/themes/bizstyle/static/bizstyle.js_t +1 -1
- sphinx/themes/bizstyle/static/css3-mediaqueries_src.js +3 -3
- sphinx/themes/bizstyle/theme.toml +12 -0
- sphinx/themes/classic/layout.html +1 -1
- sphinx/themes/classic/static/classic.css_t +1 -1
- sphinx/themes/classic/static/sidebar.js_t +1 -1
- sphinx/themes/classic/theme.toml +34 -0
- sphinx/themes/default/theme.toml +2 -0
- sphinx/themes/epub/epub-cover.html +1 -1
- sphinx/themes/epub/layout.html +1 -1
- sphinx/themes/epub/static/epub.css_t +1 -1
- sphinx/themes/epub/theme.toml +10 -0
- sphinx/themes/haiku/layout.html +3 -3
- sphinx/themes/haiku/static/haiku.css_t +2 -2
- sphinx/themes/haiku/theme.toml +16 -0
- sphinx/themes/nature/static/nature.css_t +1 -1
- sphinx/themes/nature/theme.toml +6 -0
- sphinx/themes/nonav/layout.html +1 -1
- sphinx/themes/nonav/static/nonav.css_t +1 -1
- sphinx/themes/nonav/theme.toml +10 -0
- sphinx/themes/pyramid/static/epub.css_t +1 -1
- sphinx/themes/pyramid/static/pyramid.css_t +1 -1
- sphinx/themes/pyramid/theme.toml +6 -0
- sphinx/themes/scrolls/artwork/logo.svg +1 -1
- sphinx/themes/scrolls/layout.html +2 -2
- sphinx/themes/scrolls/static/scrolls.css_t +1 -1
- sphinx/themes/scrolls/theme.toml +15 -0
- sphinx/themes/sphinxdoc/static/sphinxdoc.css_t +1 -1
- sphinx/themes/sphinxdoc/theme.toml +6 -0
- sphinx/themes/traditional/static/traditional.css_t +1 -1
- sphinx/themes/traditional/theme.toml +9 -0
- sphinx/theming.py +427 -131
- sphinx/transforms/__init__.py +21 -24
- sphinx/transforms/compact_bullet_list.py +5 -5
- sphinx/transforms/i18n.py +30 -28
- sphinx/transforms/post_transforms/__init__.py +9 -7
- sphinx/transforms/post_transforms/code.py +4 -1
- sphinx/transforms/post_transforms/images.py +17 -13
- sphinx/transforms/references.py +3 -1
- sphinx/util/__init__.py +15 -11
- sphinx/util/_io.py +34 -0
- sphinx/util/_pathlib.py +23 -18
- sphinx/util/build_phase.py +1 -0
- sphinx/util/cfamily.py +19 -11
- sphinx/util/console.py +101 -21
- sphinx/util/display.py +3 -2
- sphinx/util/docfields.py +12 -8
- sphinx/util/docutils.py +21 -35
- sphinx/util/exceptions.py +3 -2
- sphinx/util/fileutil.py +5 -5
- sphinx/util/http_date.py +9 -2
- sphinx/util/i18n.py +40 -9
- sphinx/util/inspect.py +317 -245
- sphinx/util/inventory.py +22 -5
- sphinx/util/logging.py +81 -7
- sphinx/util/matching.py +2 -1
- sphinx/util/math.py +1 -2
- sphinx/util/nodes.py +39 -29
- sphinx/util/osutil.py +25 -6
- sphinx/util/parallel.py +6 -1
- sphinx/util/requests.py +8 -5
- sphinx/util/rst.py +8 -6
- sphinx/util/tags.py +3 -3
- sphinx/util/template.py +8 -3
- sphinx/util/typing.py +76 -42
- sphinx/versioning.py +6 -2
- sphinx/writers/html.py +1 -1
- sphinx/writers/html5.py +17 -13
- sphinx/writers/latex.py +12 -12
- sphinx/writers/manpage.py +13 -7
- sphinx/writers/texinfo.py +13 -10
- sphinx/writers/text.py +13 -23
- sphinx/writers/xml.py +1 -1
- sphinx-7.2.6.dist-info/LICENSE → sphinx-7.3.1.dist-info/LICENSE.rst +1 -1
- {sphinx-7.2.6.dist-info → sphinx-7.3.1.dist-info}/METADATA +14 -12
- sphinx-7.3.1.dist-info/RECORD +581 -0
- sphinx/domains/c.py +0 -3906
- sphinx/domains/cpp.py +0 -8233
- sphinx/domains/python.py +0 -1769
- sphinx/themes/agogo/theme.conf +0 -20
- sphinx/themes/basic/theme.conf +0 -16
- sphinx/themes/bizstyle/theme.conf +0 -10
- sphinx/themes/classic/theme.conf +0 -32
- sphinx/themes/default/theme.conf +0 -2
- sphinx/themes/epub/theme.conf +0 -8
- sphinx/themes/haiku/theme.conf +0 -14
- sphinx/themes/nature/theme.conf +0 -4
- sphinx/themes/nonav/theme.conf +0 -8
- sphinx/themes/pyramid/theme.conf +0 -4
- sphinx/themes/scrolls/theme.conf +0 -13
- sphinx/themes/sphinxdoc/theme.conf +0 -4
- sphinx/themes/traditional/theme.conf +0 -7
- sphinx-7.2.6.dist-info/RECORD +0 -569
- {sphinx-7.2.6.dist-info → sphinx-7.3.1.dist-info}/WHEEL +0 -0
- {sphinx-7.2.6.dist-info → sphinx-7.3.1.dist-info}/entry_points.txt +0 -0
sphinx/ext/intersphinx.py
CHANGED
|
@@ -34,6 +34,7 @@ from docutils.utils import relative_path
|
|
|
34
34
|
import sphinx
|
|
35
35
|
from sphinx.addnodes import pending_xref
|
|
36
36
|
from sphinx.builders.html import INVENTORY_FILENAME
|
|
37
|
+
from sphinx.deprecation import _deprecation_warning
|
|
37
38
|
from sphinx.errors import ExtensionError
|
|
38
39
|
from sphinx.locale import _, __
|
|
39
40
|
from sphinx.transforms.post_transforms import ReferencesResolver
|
|
@@ -53,7 +54,7 @@ if TYPE_CHECKING:
|
|
|
53
54
|
from sphinx.config import Config
|
|
54
55
|
from sphinx.domains import Domain
|
|
55
56
|
from sphinx.environment import BuildEnvironment
|
|
56
|
-
from sphinx.util.typing import Inventory, InventoryItem, RoleFunction
|
|
57
|
+
from sphinx.util.typing import ExtensionMetadata, Inventory, InventoryItem, RoleFunction
|
|
57
58
|
|
|
58
59
|
InventoryCacheEntry = tuple[Union[str, None], int, Inventory]
|
|
59
60
|
|
|
@@ -245,7 +246,7 @@ def fetch_inventory_group(
|
|
|
245
246
|
for fail in failures:
|
|
246
247
|
logger.info(*fail)
|
|
247
248
|
else:
|
|
248
|
-
issues = '\n'.join(
|
|
249
|
+
issues = '\n'.join(f[0] % f[1:] for f in failures)
|
|
249
250
|
logger.warning(__("failed to reach any of the inventories "
|
|
250
251
|
"with the following issues:") + "\n" + issues)
|
|
251
252
|
|
|
@@ -334,8 +335,10 @@ def _resolve_reference_in_domain_by_target(
|
|
|
334
335
|
if target in inventory[objtype]:
|
|
335
336
|
# Case sensitive match, use it
|
|
336
337
|
data = inventory[objtype][target]
|
|
337
|
-
elif objtype
|
|
338
|
-
#
|
|
338
|
+
elif objtype in {'std:label', 'std:term'}:
|
|
339
|
+
# Some types require case insensitive matches:
|
|
340
|
+
# * 'term': https://github.com/sphinx-doc/sphinx/issues/9291
|
|
341
|
+
# * 'label': https://github.com/sphinx-doc/sphinx/issues/12008
|
|
339
342
|
target_lower = target.lower()
|
|
340
343
|
insensitive_matches = list(filter(lambda k: k.lower() == target_lower,
|
|
341
344
|
inventory[objtype].keys()))
|
|
@@ -479,7 +482,6 @@ def resolve_reference_detect_inventory(env: BuildEnvironment,
|
|
|
479
482
|
to form ``inv_name:newtarget``. If ``inv_name`` is a named inventory, then resolution
|
|
480
483
|
is tried in that inventory with the new target.
|
|
481
484
|
"""
|
|
482
|
-
|
|
483
485
|
# ordinary direct lookup, use data as is
|
|
484
486
|
res = resolve_reference_any_inventory(env, True, node, contnode)
|
|
485
487
|
if res is not None:
|
|
@@ -501,7 +503,6 @@ def resolve_reference_detect_inventory(env: BuildEnvironment,
|
|
|
501
503
|
def missing_reference(app: Sphinx, env: BuildEnvironment, node: pending_xref,
|
|
502
504
|
contnode: TextElement) -> nodes.reference | None:
|
|
503
505
|
"""Attempt to resolve a missing reference via intersphinx references."""
|
|
504
|
-
|
|
505
506
|
return resolve_reference_detect_inventory(env, node, contnode)
|
|
506
507
|
|
|
507
508
|
|
|
@@ -533,17 +534,90 @@ class IntersphinxRole(SphinxRole):
|
|
|
533
534
|
assert self.name == self.orig_name.lower()
|
|
534
535
|
inventory, name_suffix = self.get_inventory_and_name_suffix(self.orig_name)
|
|
535
536
|
if inventory and not inventory_exists(self.env, inventory):
|
|
536
|
-
|
|
537
|
-
|
|
537
|
+
self._emit_warning(
|
|
538
|
+
__('inventory for external cross-reference not found: %r'), inventory
|
|
539
|
+
)
|
|
538
540
|
return [], []
|
|
539
541
|
|
|
540
|
-
role_name = self.
|
|
542
|
+
domain_name, role_name = self._get_domain_role(name_suffix)
|
|
543
|
+
|
|
541
544
|
if role_name is None:
|
|
542
|
-
|
|
543
|
-
|
|
545
|
+
self._emit_warning(
|
|
546
|
+
__('invalid external cross-reference suffix: %r'), name_suffix
|
|
547
|
+
)
|
|
544
548
|
return [], []
|
|
545
549
|
|
|
546
|
-
|
|
550
|
+
# attempt to find a matching role function
|
|
551
|
+
role_func: RoleFunction | None
|
|
552
|
+
|
|
553
|
+
if domain_name is not None:
|
|
554
|
+
# the user specified a domain, so we only check that
|
|
555
|
+
if (domain := self.env.domains.get(domain_name)) is None:
|
|
556
|
+
self._emit_warning(
|
|
557
|
+
__('domain for external cross-reference not found: %r'), domain_name
|
|
558
|
+
)
|
|
559
|
+
return [], []
|
|
560
|
+
if (role_func := domain.roles.get(role_name)) is None:
|
|
561
|
+
msg = 'role for external cross-reference not found in domain %r: %r'
|
|
562
|
+
if (
|
|
563
|
+
object_types := domain.object_types.get(role_name)
|
|
564
|
+
) is not None and object_types.roles:
|
|
565
|
+
self._emit_warning(
|
|
566
|
+
__(f'{msg} (perhaps you meant one of: %s)'),
|
|
567
|
+
domain_name,
|
|
568
|
+
role_name,
|
|
569
|
+
self._concat_strings(object_types.roles),
|
|
570
|
+
)
|
|
571
|
+
else:
|
|
572
|
+
self._emit_warning(__(msg), domain_name, role_name)
|
|
573
|
+
return [], []
|
|
574
|
+
|
|
575
|
+
else:
|
|
576
|
+
# the user did not specify a domain,
|
|
577
|
+
# so we check first the default (if available) then standard domains
|
|
578
|
+
domains: list[Domain] = []
|
|
579
|
+
if default_domain := self.env.temp_data.get('default_domain'):
|
|
580
|
+
domains.append(default_domain)
|
|
581
|
+
if (
|
|
582
|
+
std_domain := self.env.domains.get('std')
|
|
583
|
+
) is not None and std_domain not in domains:
|
|
584
|
+
domains.append(std_domain)
|
|
585
|
+
|
|
586
|
+
role_func = None
|
|
587
|
+
for domain in domains:
|
|
588
|
+
if (role_func := domain.roles.get(role_name)) is not None:
|
|
589
|
+
domain_name = domain.name
|
|
590
|
+
break
|
|
591
|
+
|
|
592
|
+
if role_func is None or domain_name is None:
|
|
593
|
+
domains_str = self._concat_strings(d.name for d in domains)
|
|
594
|
+
msg = 'role for external cross-reference not found in domains %s: %r'
|
|
595
|
+
possible_roles: set[str] = set()
|
|
596
|
+
for d in domains:
|
|
597
|
+
if o := d.object_types.get(role_name):
|
|
598
|
+
possible_roles.update(f'{d.name}:{r}' for r in o.roles)
|
|
599
|
+
if possible_roles:
|
|
600
|
+
msg = f'{msg} (perhaps you meant one of: %s)'
|
|
601
|
+
self._emit_warning(
|
|
602
|
+
__(msg),
|
|
603
|
+
domains_str,
|
|
604
|
+
role_name,
|
|
605
|
+
self._concat_strings(possible_roles),
|
|
606
|
+
)
|
|
607
|
+
else:
|
|
608
|
+
self._emit_warning(__(msg), domains_str, role_name)
|
|
609
|
+
return [], []
|
|
610
|
+
|
|
611
|
+
result, messages = role_func(
|
|
612
|
+
f'{domain_name}:{role_name}',
|
|
613
|
+
self.rawtext,
|
|
614
|
+
self.text,
|
|
615
|
+
self.lineno,
|
|
616
|
+
self.inliner,
|
|
617
|
+
self.options,
|
|
618
|
+
self.content,
|
|
619
|
+
)
|
|
620
|
+
|
|
547
621
|
for node in result:
|
|
548
622
|
if isinstance(node, pending_xref):
|
|
549
623
|
node['intersphinx'] = True
|
|
@@ -552,13 +626,17 @@ class IntersphinxRole(SphinxRole):
|
|
|
552
626
|
return result, messages
|
|
553
627
|
|
|
554
628
|
def get_inventory_and_name_suffix(self, name: str) -> tuple[str | None, str]:
|
|
629
|
+
"""Extract an inventory name (if any) and ``domain+name`` suffix from a role *name*.
|
|
630
|
+
and the domain+name suffix.
|
|
631
|
+
|
|
632
|
+
The role name is expected to be of one of the following forms:
|
|
633
|
+
|
|
634
|
+
- ``external+inv:name`` -- explicit inventory and name, any domain.
|
|
635
|
+
- ``external+inv:domain:name`` -- explicit inventory, domain and name.
|
|
636
|
+
- ``external:name`` -- any inventory and domain, explicit name.
|
|
637
|
+
- ``external:domain:name`` -- any inventory, explicit domain and name.
|
|
638
|
+
"""
|
|
555
639
|
assert name.startswith('external'), name
|
|
556
|
-
# either we have an explicit inventory name, i.e,
|
|
557
|
-
# :external+inv:role: or
|
|
558
|
-
# :external+inv:domain:role:
|
|
559
|
-
# or we look in all inventories, i.e.,
|
|
560
|
-
# :external:role: or
|
|
561
|
-
# :external:domain:role:
|
|
562
640
|
suffix = name[9:]
|
|
563
641
|
if name[8] == '+':
|
|
564
642
|
inv_name, suffix = suffix.split(':', 1)
|
|
@@ -569,7 +647,39 @@ class IntersphinxRole(SphinxRole):
|
|
|
569
647
|
msg = f'Malformed :external: role name: {name}'
|
|
570
648
|
raise ValueError(msg)
|
|
571
649
|
|
|
650
|
+
def _get_domain_role(self, name: str) -> tuple[str | None, str | None]:
|
|
651
|
+
"""Convert the *name* string into a domain and a role name.
|
|
652
|
+
|
|
653
|
+
- If *name* contains no ``:``, return ``(None, name)``.
|
|
654
|
+
- If *name* contains a single ``:``, the domain/role is split on this.
|
|
655
|
+
- If *name* contains multiple ``:``, return ``(None, None)``.
|
|
656
|
+
"""
|
|
657
|
+
names = name.split(':')
|
|
658
|
+
if len(names) == 1:
|
|
659
|
+
return None, names[0]
|
|
660
|
+
elif len(names) == 2:
|
|
661
|
+
return names[0], names[1]
|
|
662
|
+
else:
|
|
663
|
+
return None, None
|
|
664
|
+
|
|
665
|
+
def _emit_warning(self, msg: str, /, *args: Any) -> None:
|
|
666
|
+
logger.warning(
|
|
667
|
+
msg,
|
|
668
|
+
*args,
|
|
669
|
+
type='intersphinx',
|
|
670
|
+
subtype='external',
|
|
671
|
+
location=(self.env.docname, self.lineno),
|
|
672
|
+
)
|
|
673
|
+
|
|
674
|
+
def _concat_strings(self, strings: Iterable[str]) -> str:
|
|
675
|
+
return ', '.join(f'{s!r}' for s in sorted(strings))
|
|
676
|
+
|
|
677
|
+
# deprecated methods
|
|
678
|
+
|
|
572
679
|
def get_role_name(self, name: str) -> tuple[str, str] | None:
|
|
680
|
+
_deprecation_warning(
|
|
681
|
+
__name__, f'{self.__class__.__name__}.get_role_name', '', remove=(9, 0)
|
|
682
|
+
)
|
|
573
683
|
names = name.split(':')
|
|
574
684
|
if len(names) == 1:
|
|
575
685
|
# role
|
|
@@ -591,6 +701,9 @@ class IntersphinxRole(SphinxRole):
|
|
|
591
701
|
return None
|
|
592
702
|
|
|
593
703
|
def is_existent_role(self, domain_name: str, role_name: str) -> bool:
|
|
704
|
+
_deprecation_warning(
|
|
705
|
+
__name__, f'{self.__class__.__name__}.is_existent_role', '', remove=(9, 0)
|
|
706
|
+
)
|
|
594
707
|
try:
|
|
595
708
|
domain = self.env.get_domain(domain_name)
|
|
596
709
|
return role_name in domain.roles
|
|
@@ -598,6 +711,10 @@ class IntersphinxRole(SphinxRole):
|
|
|
598
711
|
return False
|
|
599
712
|
|
|
600
713
|
def invoke_role(self, role: tuple[str, str]) -> tuple[list[Node], list[system_message]]:
|
|
714
|
+
"""Invoke the role described by a ``(domain, role name)`` pair."""
|
|
715
|
+
_deprecation_warning(
|
|
716
|
+
__name__, f'{self.__class__.__name__}.invoke_role', '', remove=(9, 0)
|
|
717
|
+
)
|
|
601
718
|
domain = self.env.get_domain(role[0])
|
|
602
719
|
if domain:
|
|
603
720
|
role_func = domain.role(role[1])
|
|
@@ -681,11 +798,11 @@ def normalize_intersphinx_mapping(app: Sphinx, config: Config) -> None:
|
|
|
681
798
|
config.intersphinx_mapping.pop(key)
|
|
682
799
|
|
|
683
800
|
|
|
684
|
-
def setup(app: Sphinx) ->
|
|
685
|
-
app.add_config_value('intersphinx_mapping', {},
|
|
686
|
-
app.add_config_value('intersphinx_cache_limit', 5,
|
|
687
|
-
app.add_config_value('intersphinx_timeout', None,
|
|
688
|
-
app.add_config_value('intersphinx_disabled_reftypes', ['std:doc'],
|
|
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')
|
|
689
806
|
app.connect('config-inited', normalize_intersphinx_mapping, priority=800)
|
|
690
807
|
app.connect('builder-inited', load_mappings)
|
|
691
808
|
app.connect('source-read', install_dispatcher)
|
sphinx/ext/linkcode.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from typing import TYPE_CHECKING
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
6
|
|
|
7
7
|
from docutils import nodes
|
|
8
8
|
|
|
@@ -15,6 +15,7 @@ if TYPE_CHECKING:
|
|
|
15
15
|
from docutils.nodes import Node
|
|
16
16
|
|
|
17
17
|
from sphinx.application import Sphinx
|
|
18
|
+
from sphinx.util.typing import ExtensionMetadata
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
class LinkcodeError(SphinxError):
|
|
@@ -71,7 +72,7 @@ def doctree_read(app: Sphinx, doctree: Node) -> None:
|
|
|
71
72
|
signode += onlynode
|
|
72
73
|
|
|
73
74
|
|
|
74
|
-
def setup(app: Sphinx) ->
|
|
75
|
+
def setup(app: Sphinx) -> ExtensionMetadata:
|
|
75
76
|
app.connect('doctree-read', doctree_read)
|
|
76
77
|
app.add_config_value('linkcode_resolve', None, '')
|
|
77
78
|
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
|
sphinx/ext/mathjax.py
CHANGED
|
@@ -21,6 +21,7 @@ from sphinx.util.math import get_node_equation_number
|
|
|
21
21
|
|
|
22
22
|
if TYPE_CHECKING:
|
|
23
23
|
from sphinx.application import Sphinx
|
|
24
|
+
from sphinx.util.typing import ExtensionMetadata
|
|
24
25
|
from sphinx.writers.html import HTML5Translator
|
|
25
26
|
|
|
26
27
|
# more information for mathjax secure url is here:
|
|
@@ -109,7 +110,7 @@ def install_mathjax(app: Sphinx, pagename: str, templatename: str, context: dict
|
|
|
109
110
|
builder.add_js_file(app.config.mathjax_path, **options)
|
|
110
111
|
|
|
111
112
|
|
|
112
|
-
def setup(app: Sphinx) ->
|
|
113
|
+
def setup(app: Sphinx) -> ExtensionMetadata:
|
|
113
114
|
app.add_html_math_renderer('mathjax',
|
|
114
115
|
(html_visit_math, None),
|
|
115
116
|
(html_visit_displaymath, None))
|
sphinx/ext/napoleon/__init__.py
CHANGED
|
@@ -2,13 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from typing import Any
|
|
5
|
+
from typing import TYPE_CHECKING, Any
|
|
6
6
|
|
|
7
7
|
import sphinx
|
|
8
8
|
from sphinx.application import Sphinx
|
|
9
9
|
from sphinx.ext.napoleon.docstring import GoogleDocstring, NumpyDocstring
|
|
10
10
|
from sphinx.util import inspect
|
|
11
11
|
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from sphinx.config import _ConfigRebuild
|
|
14
|
+
from sphinx.util.typing import ExtensionMetadata
|
|
15
|
+
|
|
12
16
|
|
|
13
17
|
class Config:
|
|
14
18
|
"""Sphinx napoleon extension settings in `conf.py`.
|
|
@@ -261,8 +265,9 @@ class Config:
|
|
|
261
265
|
Use the type annotations of class attributes that are documented in the docstring
|
|
262
266
|
but do not have a type in the docstring.
|
|
263
267
|
|
|
264
|
-
"""
|
|
265
|
-
|
|
268
|
+
""" # NoQA: D301
|
|
269
|
+
|
|
270
|
+
_config_values: dict[str, tuple[Any, _ConfigRebuild]] = {
|
|
266
271
|
'napoleon_google_docstring': (True, 'env'),
|
|
267
272
|
'napoleon_numpy_docstring': (True, 'env'),
|
|
268
273
|
'napoleon_include_init_with_doc': (False, 'env'),
|
|
@@ -288,7 +293,7 @@ class Config:
|
|
|
288
293
|
setattr(self, name, value)
|
|
289
294
|
|
|
290
295
|
|
|
291
|
-
def setup(app: Sphinx) ->
|
|
296
|
+
def setup(app: Sphinx) -> ExtensionMetadata:
|
|
292
297
|
"""Sphinx extension setup function.
|
|
293
298
|
|
|
294
299
|
When the extension is loaded, Sphinx imports this module and executes
|
|
@@ -326,7 +331,7 @@ def setup(app: Sphinx) -> dict[str, Any]:
|
|
|
326
331
|
|
|
327
332
|
|
|
328
333
|
def _patch_python_domain() -> None:
|
|
329
|
-
from sphinx.domains.python import PyObject, PyTypedField
|
|
334
|
+
from sphinx.domains.python._object import PyObject, PyTypedField
|
|
330
335
|
from sphinx.locale import _
|
|
331
336
|
for doc_field in PyObject.doc_field_types:
|
|
332
337
|
if doc_field.name == 'parameter':
|
|
@@ -335,7 +340,7 @@ def _patch_python_domain() -> None:
|
|
|
335
340
|
PyObject.doc_field_types.append(
|
|
336
341
|
PyTypedField('keyword', label=_('Keyword Arguments'),
|
|
337
342
|
names=('keyword', 'kwarg', 'kwparam'),
|
|
338
|
-
typerolename='
|
|
343
|
+
typerolename='class', typenames=('paramtype', 'kwtype'),
|
|
339
344
|
can_collapse=True))
|
|
340
345
|
|
|
341
346
|
|
|
@@ -386,7 +391,7 @@ def _process_docstring(app: Sphinx, what: str, name: str, obj: Any,
|
|
|
386
391
|
docstring = GoogleDocstring(result_lines, app.config, app, what, name,
|
|
387
392
|
obj, options)
|
|
388
393
|
result_lines = docstring.lines()
|
|
389
|
-
lines[:] = result_lines
|
|
394
|
+
lines[:] = result_lines.copy()
|
|
390
395
|
|
|
391
396
|
|
|
392
397
|
def _skip_member(app: Sphinx, what: str, name: str, obj: Any,
|
sphinx/ext/napoleon/docstring.py
CHANGED
|
@@ -7,6 +7,7 @@ import contextlib
|
|
|
7
7
|
import inspect
|
|
8
8
|
import re
|
|
9
9
|
from functools import partial
|
|
10
|
+
from itertools import starmap
|
|
10
11
|
from typing import TYPE_CHECKING, Any, Callable
|
|
11
12
|
|
|
12
13
|
from sphinx.locale import _, __
|
|
@@ -14,6 +15,8 @@ from sphinx.util import logging
|
|
|
14
15
|
from sphinx.util.typing import get_type_hints, stringify_annotation
|
|
15
16
|
|
|
16
17
|
if TYPE_CHECKING:
|
|
18
|
+
from collections.abc import Iterator
|
|
19
|
+
|
|
17
20
|
from sphinx.application import Sphinx
|
|
18
21
|
from sphinx.config import Config as SphinxConfig
|
|
19
22
|
|
|
@@ -145,7 +148,7 @@ class GoogleDocstring:
|
|
|
145
148
|
"""
|
|
146
149
|
|
|
147
150
|
_name_rgx = re.compile(r"^\s*((?::(?P<role>\S+):)?`(?P<name>~?[a-zA-Z0-9_.-]+)`|"
|
|
148
|
-
r" (?P<name2>~?[a-zA-Z0-9_.-]+))\s*", re.
|
|
151
|
+
r" (?P<name2>~?[a-zA-Z0-9_.-]+))\s*", re.VERBOSE)
|
|
149
152
|
|
|
150
153
|
def __init__(
|
|
151
154
|
self,
|
|
@@ -304,19 +307,18 @@ class GoogleDocstring:
|
|
|
304
307
|
_type = _convert_type_spec(_type, self._config.napoleon_type_aliases or {})
|
|
305
308
|
|
|
306
309
|
indent = self._get_indent(line) + 1
|
|
307
|
-
_descs = [_desc
|
|
310
|
+
_descs = [_desc, *self._dedent(self._consume_indented_block(indent))]
|
|
308
311
|
_descs = self.__class__(_descs, self._config).lines()
|
|
309
312
|
return _name, _type, _descs
|
|
310
313
|
|
|
311
314
|
def _consume_fields(self, parse_type: bool = True, prefer_type: bool = False,
|
|
312
315
|
multiple: bool = False) -> list[tuple[str, str, list[str]]]:
|
|
313
316
|
self._consume_empty()
|
|
314
|
-
fields = []
|
|
317
|
+
fields: list[tuple[str, str, list[str]]] = []
|
|
315
318
|
while not self._is_section_break():
|
|
316
319
|
_name, _type, _desc = self._consume_field(parse_type, prefer_type)
|
|
317
320
|
if multiple and _name:
|
|
318
|
-
for name in _name.split(",")
|
|
319
|
-
fields.append((name.strip(), _type, _desc))
|
|
321
|
+
fields.extend((name.strip(), _type, _desc) for name in _name.split(","))
|
|
320
322
|
elif _name or _type or _desc:
|
|
321
323
|
fields.append((_name, _type, _desc))
|
|
322
324
|
return fields
|
|
@@ -327,7 +329,7 @@ class GoogleDocstring:
|
|
|
327
329
|
if not colon or not _desc:
|
|
328
330
|
_type, _desc = _desc, _type
|
|
329
331
|
_desc += colon
|
|
330
|
-
_descs = [_desc
|
|
332
|
+
_descs = [_desc, *self._dedent(self._consume_to_end())]
|
|
331
333
|
_descs = self.__class__(_descs, self._config).lines()
|
|
332
334
|
return _type, _descs
|
|
333
335
|
|
|
@@ -399,15 +401,15 @@ class GoogleDocstring:
|
|
|
399
401
|
|
|
400
402
|
def _fix_field_desc(self, desc: list[str]) -> list[str]:
|
|
401
403
|
if self._is_list(desc):
|
|
402
|
-
desc = [''
|
|
404
|
+
desc = ['', *desc]
|
|
403
405
|
elif desc[0].endswith('::'):
|
|
404
406
|
desc_block = desc[1:]
|
|
405
407
|
indent = self._get_indent(desc[0])
|
|
406
408
|
block_indent = self._get_initial_indent(desc_block)
|
|
407
409
|
if block_indent > indent:
|
|
408
|
-
desc = [''
|
|
410
|
+
desc = ['', *desc]
|
|
409
411
|
else:
|
|
410
|
-
desc = ['', desc[0]
|
|
412
|
+
desc = ['', desc[0], *self._indent(desc_block, 4)]
|
|
411
413
|
return desc
|
|
412
414
|
|
|
413
415
|
def _format_admonition(self, admonition: str, lines: list[str]) -> list[str]:
|
|
@@ -416,7 +418,7 @@ class GoogleDocstring:
|
|
|
416
418
|
return [f'.. {admonition}:: {lines[0].strip()}', '']
|
|
417
419
|
elif lines:
|
|
418
420
|
lines = self._indent(self._dedent(lines), 3)
|
|
419
|
-
return ['.. %s::' % admonition, ''
|
|
421
|
+
return ['.. %s::' % admonition, '', *lines, '']
|
|
420
422
|
else:
|
|
421
423
|
return ['.. %s::' % admonition, '']
|
|
422
424
|
|
|
@@ -453,7 +455,7 @@ class GoogleDocstring:
|
|
|
453
455
|
|
|
454
456
|
if _type:
|
|
455
457
|
lines.append(f':{type_role} {_name}: {_type}')
|
|
456
|
-
return lines
|
|
458
|
+
return [*lines, '']
|
|
457
459
|
|
|
458
460
|
def _format_field(self, _name: str, _type: str, _desc: list[str]) -> list[str]:
|
|
459
461
|
_desc = self._strip_empty(_desc)
|
|
@@ -480,7 +482,7 @@ class GoogleDocstring:
|
|
|
480
482
|
if _desc[0]:
|
|
481
483
|
return [field + _desc[0]] + _desc[1:]
|
|
482
484
|
else:
|
|
483
|
-
return [field
|
|
485
|
+
return [field, *_desc]
|
|
484
486
|
else:
|
|
485
487
|
return [field]
|
|
486
488
|
|
|
@@ -537,7 +539,7 @@ class GoogleDocstring:
|
|
|
537
539
|
return [(' ' * n) + line for line in lines]
|
|
538
540
|
|
|
539
541
|
def _is_indented(self, line: str, indent: int = 1) -> bool:
|
|
540
|
-
for i, s in enumerate(line): #
|
|
542
|
+
for i, s in enumerate(line): # NoQA: SIM110
|
|
541
543
|
if i >= indent:
|
|
542
544
|
return True
|
|
543
545
|
elif not s.isspace():
|
|
@@ -623,7 +625,7 @@ class GoogleDocstring:
|
|
|
623
625
|
self._is_in_section = True
|
|
624
626
|
self._section_indent = self._get_current_indent()
|
|
625
627
|
if _directive_regex.match(section):
|
|
626
|
-
lines = [section
|
|
628
|
+
lines = [section, *self._consume_to_next_section()]
|
|
627
629
|
else:
|
|
628
630
|
lines = self._sections[section.lower()](section)
|
|
629
631
|
finally:
|
|
@@ -711,7 +713,7 @@ class GoogleDocstring:
|
|
|
711
713
|
else:
|
|
712
714
|
header = '.. rubric:: %s' % section
|
|
713
715
|
if lines:
|
|
714
|
-
return [header, ''
|
|
716
|
+
return [header, '', *lines, '']
|
|
715
717
|
else:
|
|
716
718
|
return [header, '']
|
|
717
719
|
|
|
@@ -733,7 +735,7 @@ class GoogleDocstring:
|
|
|
733
735
|
if 'no-index' in self._opt or 'noindex' in self._opt:
|
|
734
736
|
lines.append(' :no-index:')
|
|
735
737
|
if _desc:
|
|
736
|
-
lines.extend([''
|
|
738
|
+
lines.extend(['', *self._indent(_desc, 3)])
|
|
737
739
|
lines.append('')
|
|
738
740
|
return lines
|
|
739
741
|
|
|
@@ -888,7 +890,7 @@ def _recombine_set_tokens(tokens: list[str]) -> list[str]:
|
|
|
888
890
|
token_queue = collections.deque(tokens)
|
|
889
891
|
keywords = ("optional", "default")
|
|
890
892
|
|
|
891
|
-
def takewhile_set(tokens):
|
|
893
|
+
def takewhile_set(tokens: collections.deque[str]) -> Iterator[str]:
|
|
892
894
|
open_braces = 0
|
|
893
895
|
previous_token = None
|
|
894
896
|
while True:
|
|
@@ -924,7 +926,7 @@ def _recombine_set_tokens(tokens: list[str]) -> list[str]:
|
|
|
924
926
|
if open_braces == 0:
|
|
925
927
|
break
|
|
926
928
|
|
|
927
|
-
def combine_set(tokens):
|
|
929
|
+
def combine_set(tokens: collections.deque[str]) -> Iterator[str]:
|
|
928
930
|
while True:
|
|
929
931
|
try:
|
|
930
932
|
token = tokens.popleft()
|
|
@@ -941,7 +943,7 @@ def _recombine_set_tokens(tokens: list[str]) -> list[str]:
|
|
|
941
943
|
|
|
942
944
|
|
|
943
945
|
def _tokenize_type_spec(spec: str) -> list[str]:
|
|
944
|
-
def postprocess(item):
|
|
946
|
+
def postprocess(item: str) -> list[str]:
|
|
945
947
|
if _default_regex.match(item):
|
|
946
948
|
default = item[:7]
|
|
947
949
|
# can't be separated by anything other than a single space
|
|
@@ -962,7 +964,7 @@ def _tokenize_type_spec(spec: str) -> list[str]:
|
|
|
962
964
|
|
|
963
965
|
|
|
964
966
|
def _token_type(token: str, location: str | None = None) -> str:
|
|
965
|
-
def is_numeric(token):
|
|
967
|
+
def is_numeric(token: str) -> bool:
|
|
966
968
|
try:
|
|
967
969
|
# use complex to make sure every numeric value is detected as literal
|
|
968
970
|
complex(token)
|
|
@@ -1026,7 +1028,7 @@ def _convert_numpy_type_spec(
|
|
|
1026
1028
|
if translations is None:
|
|
1027
1029
|
translations = {}
|
|
1028
1030
|
|
|
1029
|
-
def convert_obj(obj, translations, default_translation):
|
|
1031
|
+
def convert_obj(obj: str, translations: dict[str, str], default_translation: str) -> str:
|
|
1030
1032
|
translation = translations.get(obj, obj)
|
|
1031
1033
|
|
|
1032
1034
|
# use :class: (the default) only if obj is not a standard singleton
|
|
@@ -1155,6 +1157,7 @@ class NumpyDocstring(GoogleDocstring):
|
|
|
1155
1157
|
The lines of the docstring in a list.
|
|
1156
1158
|
|
|
1157
1159
|
"""
|
|
1160
|
+
|
|
1158
1161
|
def __init__(
|
|
1159
1162
|
self,
|
|
1160
1163
|
docstring: str | list[str],
|
|
@@ -1180,13 +1183,13 @@ class NumpyDocstring(GoogleDocstring):
|
|
|
1180
1183
|
elif filepath is None:
|
|
1181
1184
|
filepath = ""
|
|
1182
1185
|
|
|
1183
|
-
return ":
|
|
1186
|
+
return f"{filepath}:docstring of {name}"
|
|
1184
1187
|
|
|
1185
1188
|
def _escape_args_and_kwargs(self, name: str) -> str:
|
|
1186
1189
|
func = super()._escape_args_and_kwargs
|
|
1187
1190
|
|
|
1188
1191
|
if ", " in name:
|
|
1189
|
-
return ", ".join(func
|
|
1192
|
+
return ", ".join(map(func, name.split(", ")))
|
|
1190
1193
|
else:
|
|
1191
1194
|
return func(name)
|
|
1192
1195
|
|
|
@@ -1233,7 +1236,7 @@ class NumpyDocstring(GoogleDocstring):
|
|
|
1233
1236
|
line1, line2 = self._lines.get(0), self._lines.get(1)
|
|
1234
1237
|
return (not self._lines or
|
|
1235
1238
|
self._is_section_header() or
|
|
1236
|
-
|
|
1239
|
+
(line1 == line2 == '') or
|
|
1237
1240
|
(self._is_in_section and
|
|
1238
1241
|
line1 and
|
|
1239
1242
|
not self._is_indented(line1, self._section_indent)))
|
|
@@ -1269,7 +1272,7 @@ class NumpyDocstring(GoogleDocstring):
|
|
|
1269
1272
|
func_name1, func_name2, :meth:`func_name`, func_name3
|
|
1270
1273
|
|
|
1271
1274
|
"""
|
|
1272
|
-
items = []
|
|
1275
|
+
items: list[tuple[str, list[str], str | None]] = []
|
|
1273
1276
|
|
|
1274
1277
|
def parse_item_name(text: str) -> tuple[str, str | None]:
|
|
1275
1278
|
"""Match ':role:`name`' or 'name'"""
|
|
@@ -1286,10 +1289,12 @@ class NumpyDocstring(GoogleDocstring):
|
|
|
1286
1289
|
if not name:
|
|
1287
1290
|
return
|
|
1288
1291
|
name, role = parse_item_name(name)
|
|
1289
|
-
items.append((name,
|
|
1290
|
-
|
|
1292
|
+
items.append((name, rest.copy(), role))
|
|
1293
|
+
rest.clear()
|
|
1291
1294
|
|
|
1292
|
-
def translate(
|
|
1295
|
+
def translate(
|
|
1296
|
+
func: str, description: list[str], role: str | None,
|
|
1297
|
+
) -> tuple[str, list[str], str | None]:
|
|
1293
1298
|
translations = self._config.napoleon_type_aliases
|
|
1294
1299
|
if role is not None or not translations:
|
|
1295
1300
|
return func, description, role
|
|
@@ -1336,10 +1341,7 @@ class NumpyDocstring(GoogleDocstring):
|
|
|
1336
1341
|
return []
|
|
1337
1342
|
|
|
1338
1343
|
# apply type aliases
|
|
1339
|
-
items =
|
|
1340
|
-
translate(func, description, role)
|
|
1341
|
-
for func, description, role in items
|
|
1342
|
-
]
|
|
1344
|
+
items = list(starmap(translate, items))
|
|
1343
1345
|
|
|
1344
1346
|
lines: list[str] = []
|
|
1345
1347
|
last_had_desc = True
|
sphinx/ext/todo.py
CHANGED
|
@@ -7,7 +7,9 @@ with a backlink to the original location.
|
|
|
7
7
|
|
|
8
8
|
from __future__ import annotations
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
import functools
|
|
11
|
+
import operator
|
|
12
|
+
from typing import TYPE_CHECKING, Any, ClassVar, cast
|
|
11
13
|
|
|
12
14
|
from docutils import nodes
|
|
13
15
|
from docutils.parsers.rst import directives
|
|
@@ -26,7 +28,7 @@ if TYPE_CHECKING:
|
|
|
26
28
|
|
|
27
29
|
from sphinx.application import Sphinx
|
|
28
30
|
from sphinx.environment import BuildEnvironment
|
|
29
|
-
from sphinx.util.typing import OptionSpec
|
|
31
|
+
from sphinx.util.typing import ExtensionMetadata, OptionSpec
|
|
30
32
|
from sphinx.writers.html import HTML5Translator
|
|
31
33
|
from sphinx.writers.latex import LaTeXTranslator
|
|
32
34
|
|
|
@@ -51,7 +53,7 @@ class Todo(BaseAdmonition, SphinxDirective):
|
|
|
51
53
|
required_arguments = 0
|
|
52
54
|
optional_arguments = 0
|
|
53
55
|
final_argument_whitespace = False
|
|
54
|
-
option_spec: OptionSpec = {
|
|
56
|
+
option_spec: ClassVar[OptionSpec] = {
|
|
55
57
|
'class': directives.class_option,
|
|
56
58
|
'name': directives.unchanged,
|
|
57
59
|
}
|
|
@@ -85,7 +87,7 @@ class TodoDomain(Domain):
|
|
|
85
87
|
def clear_doc(self, docname: str) -> None:
|
|
86
88
|
self.todos.pop(docname, None)
|
|
87
89
|
|
|
88
|
-
def merge_domaindata(self, docnames: list[str], otherdata: dict) -> None:
|
|
90
|
+
def merge_domaindata(self, docnames: list[str], otherdata: dict[str, Any]) -> None:
|
|
89
91
|
for docname in docnames:
|
|
90
92
|
self.todos[docname] = otherdata['todos'][docname]
|
|
91
93
|
|
|
@@ -110,7 +112,7 @@ class TodoList(SphinxDirective):
|
|
|
110
112
|
required_arguments = 0
|
|
111
113
|
optional_arguments = 0
|
|
112
114
|
final_argument_whitespace = False
|
|
113
|
-
option_spec: OptionSpec = {}
|
|
115
|
+
option_spec: ClassVar[OptionSpec] = {}
|
|
114
116
|
|
|
115
117
|
def run(self) -> list[Node]:
|
|
116
118
|
# Simply insert an empty todolist node which will be replaced later
|
|
@@ -129,7 +131,8 @@ class TodoListProcessor:
|
|
|
129
131
|
self.process(doctree, docname)
|
|
130
132
|
|
|
131
133
|
def process(self, doctree: nodes.document, docname: str) -> None:
|
|
132
|
-
todos: list[todo_node] =
|
|
134
|
+
todos: list[todo_node] = functools.reduce(
|
|
135
|
+
operator.iadd, self.domain.todos.values(), [])
|
|
133
136
|
for node in list(doctree.findall(todolist)):
|
|
134
137
|
if not self.config.todo_include_todos:
|
|
135
138
|
node.parent.remove(node)
|
|
@@ -221,7 +224,7 @@ def latex_depart_todo_node(self: LaTeXTranslator, node: todo_node) -> None:
|
|
|
221
224
|
self.body.append('\\end{sphinxadmonition}\n')
|
|
222
225
|
|
|
223
226
|
|
|
224
|
-
def setup(app: Sphinx) ->
|
|
227
|
+
def setup(app: Sphinx) -> ExtensionMetadata:
|
|
225
228
|
app.add_event('todo-defined')
|
|
226
229
|
app.add_config_value('todo_include_todos', False, 'html')
|
|
227
230
|
app.add_config_value('todo_link_only', False, 'html')
|