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
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import contextlib
|
|
4
|
+
import re
|
|
5
|
+
from typing import TYPE_CHECKING, ClassVar
|
|
6
|
+
|
|
7
|
+
from docutils import nodes
|
|
8
|
+
from docutils.parsers.rst import directives
|
|
9
|
+
|
|
10
|
+
from sphinx import addnodes
|
|
11
|
+
from sphinx.addnodes import desc_signature, pending_xref, pending_xref_condition
|
|
12
|
+
from sphinx.directives import ObjectDescription
|
|
13
|
+
from sphinx.domains.python._annotations import (
|
|
14
|
+
_parse_annotation,
|
|
15
|
+
_parse_arglist,
|
|
16
|
+
_parse_type_list,
|
|
17
|
+
_pseudo_parse_arglist,
|
|
18
|
+
parse_reftarget,
|
|
19
|
+
)
|
|
20
|
+
from sphinx.locale import _
|
|
21
|
+
from sphinx.util import logging
|
|
22
|
+
from sphinx.util.docfields import Field, GroupedField, TypedField
|
|
23
|
+
from sphinx.util.nodes import (
|
|
24
|
+
make_id,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
if TYPE_CHECKING:
|
|
28
|
+
|
|
29
|
+
from docutils.nodes import Node
|
|
30
|
+
from docutils.parsers.rst.states import Inliner
|
|
31
|
+
|
|
32
|
+
from sphinx.environment import BuildEnvironment
|
|
33
|
+
from sphinx.util.typing import OptionSpec, TextlikeNode
|
|
34
|
+
|
|
35
|
+
logger = logging.getLogger(__name__)
|
|
36
|
+
|
|
37
|
+
# REs for Python signatures
|
|
38
|
+
py_sig_re = re.compile(
|
|
39
|
+
r'''^ ([\w.]*\.)? # class name(s)
|
|
40
|
+
(\w+) \s* # thing name
|
|
41
|
+
(?: \[\s*(.*)\s*])? # optional: type parameters list
|
|
42
|
+
(?: \(\s*(.*)\s*\) # optional: arguments
|
|
43
|
+
(?:\s* -> \s* (.*))? # return annotation
|
|
44
|
+
)? $ # and nothing more
|
|
45
|
+
''', re.VERBOSE)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
# This override allows our inline type specifiers to behave like :class: link
|
|
49
|
+
# when it comes to handling "." and "~" prefixes.
|
|
50
|
+
class PyXrefMixin:
|
|
51
|
+
def make_xref(
|
|
52
|
+
self,
|
|
53
|
+
rolename: str,
|
|
54
|
+
domain: str,
|
|
55
|
+
target: str,
|
|
56
|
+
innernode: type[TextlikeNode] = nodes.emphasis,
|
|
57
|
+
contnode: Node | None = None,
|
|
58
|
+
env: BuildEnvironment | None = None,
|
|
59
|
+
inliner: Inliner | None = None,
|
|
60
|
+
location: Node | None = None,
|
|
61
|
+
) -> Node:
|
|
62
|
+
# we use inliner=None to make sure we get the old behaviour with a single
|
|
63
|
+
# pending_xref node
|
|
64
|
+
result = super().make_xref(rolename, domain, target, # type: ignore[misc]
|
|
65
|
+
innernode, contnode,
|
|
66
|
+
env, inliner=None, location=None)
|
|
67
|
+
if isinstance(result, pending_xref):
|
|
68
|
+
assert env is not None
|
|
69
|
+
result['refspecific'] = True
|
|
70
|
+
result['py:module'] = env.ref_context.get('py:module')
|
|
71
|
+
result['py:class'] = env.ref_context.get('py:class')
|
|
72
|
+
|
|
73
|
+
reftype, reftarget, reftitle, _ = parse_reftarget(target)
|
|
74
|
+
if reftarget != reftitle:
|
|
75
|
+
result['reftype'] = reftype
|
|
76
|
+
result['reftarget'] = reftarget
|
|
77
|
+
|
|
78
|
+
result.clear()
|
|
79
|
+
result += innernode(reftitle, reftitle) # type: ignore[call-arg]
|
|
80
|
+
elif env.config.python_use_unqualified_type_names:
|
|
81
|
+
children = result.children
|
|
82
|
+
result.clear()
|
|
83
|
+
|
|
84
|
+
shortname = target.split('.')[-1]
|
|
85
|
+
textnode = innernode('', shortname) # type: ignore[call-arg]
|
|
86
|
+
contnodes = [pending_xref_condition('', '', textnode, condition='resolved'),
|
|
87
|
+
pending_xref_condition('', '', *children, condition='*')]
|
|
88
|
+
result.extend(contnodes)
|
|
89
|
+
|
|
90
|
+
return result
|
|
91
|
+
|
|
92
|
+
def make_xrefs(
|
|
93
|
+
self,
|
|
94
|
+
rolename: str,
|
|
95
|
+
domain: str,
|
|
96
|
+
target: str,
|
|
97
|
+
innernode: type[TextlikeNode] = nodes.emphasis,
|
|
98
|
+
contnode: Node | None = None,
|
|
99
|
+
env: BuildEnvironment | None = None,
|
|
100
|
+
inliner: Inliner | None = None,
|
|
101
|
+
location: Node | None = None,
|
|
102
|
+
) -> list[Node]:
|
|
103
|
+
delims = r'(\s*[\[\]\(\),](?:\s*o[rf]\s)?\s*|\s+o[rf]\s+|\s*\|\s*|\.\.\.)'
|
|
104
|
+
delims_re = re.compile(delims)
|
|
105
|
+
sub_targets = re.split(delims, target)
|
|
106
|
+
|
|
107
|
+
split_contnode = bool(contnode and contnode.astext() == target)
|
|
108
|
+
|
|
109
|
+
in_literal = False
|
|
110
|
+
results = []
|
|
111
|
+
for sub_target in filter(None, sub_targets):
|
|
112
|
+
if split_contnode:
|
|
113
|
+
contnode = nodes.Text(sub_target)
|
|
114
|
+
|
|
115
|
+
if in_literal or delims_re.match(sub_target):
|
|
116
|
+
results.append(contnode or innernode(sub_target, sub_target)) # type: ignore[call-arg]
|
|
117
|
+
else:
|
|
118
|
+
results.append(self.make_xref(rolename, domain, sub_target,
|
|
119
|
+
innernode, contnode, env, inliner, location))
|
|
120
|
+
|
|
121
|
+
if sub_target in ('Literal', 'typing.Literal', '~typing.Literal'):
|
|
122
|
+
in_literal = True
|
|
123
|
+
|
|
124
|
+
return results
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class PyField(PyXrefMixin, Field):
|
|
128
|
+
pass
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class PyGroupedField(PyXrefMixin, GroupedField):
|
|
132
|
+
pass
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class PyTypedField(PyXrefMixin, TypedField):
|
|
136
|
+
pass
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
class PyObject(ObjectDescription[tuple[str, str]]):
|
|
140
|
+
"""
|
|
141
|
+
Description of a general Python object.
|
|
142
|
+
|
|
143
|
+
:cvar allow_nesting: Class is an object that allows for nested namespaces
|
|
144
|
+
:vartype allow_nesting: bool
|
|
145
|
+
"""
|
|
146
|
+
|
|
147
|
+
option_spec: ClassVar[OptionSpec] = {
|
|
148
|
+
'no-index': directives.flag,
|
|
149
|
+
'no-index-entry': directives.flag,
|
|
150
|
+
'no-contents-entry': directives.flag,
|
|
151
|
+
'no-typesetting': directives.flag,
|
|
152
|
+
'noindex': directives.flag,
|
|
153
|
+
'noindexentry': directives.flag,
|
|
154
|
+
'nocontentsentry': directives.flag,
|
|
155
|
+
'single-line-parameter-list': directives.flag,
|
|
156
|
+
'single-line-type-parameter-list': directives.flag,
|
|
157
|
+
'module': directives.unchanged,
|
|
158
|
+
'canonical': directives.unchanged,
|
|
159
|
+
'annotation': directives.unchanged,
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
doc_field_types = [
|
|
163
|
+
PyTypedField('parameter', label=_('Parameters'),
|
|
164
|
+
names=('param', 'parameter', 'arg', 'argument',
|
|
165
|
+
'keyword', 'kwarg', 'kwparam'),
|
|
166
|
+
typerolename='class', typenames=('paramtype', 'type'),
|
|
167
|
+
can_collapse=True),
|
|
168
|
+
PyTypedField('variable', label=_('Variables'),
|
|
169
|
+
names=('var', 'ivar', 'cvar'),
|
|
170
|
+
typerolename='class', typenames=('vartype',),
|
|
171
|
+
can_collapse=True),
|
|
172
|
+
PyGroupedField('exceptions', label=_('Raises'), rolename='exc',
|
|
173
|
+
names=('raises', 'raise', 'exception', 'except'),
|
|
174
|
+
can_collapse=True),
|
|
175
|
+
Field('returnvalue', label=_('Returns'), has_arg=False,
|
|
176
|
+
names=('returns', 'return')),
|
|
177
|
+
PyField('returntype', label=_('Return type'), has_arg=False,
|
|
178
|
+
names=('rtype',), bodyrolename='class'),
|
|
179
|
+
]
|
|
180
|
+
|
|
181
|
+
allow_nesting = False
|
|
182
|
+
|
|
183
|
+
def get_signature_prefix(self, sig: str) -> list[nodes.Node]:
|
|
184
|
+
"""May return a prefix to put before the object name in the
|
|
185
|
+
signature.
|
|
186
|
+
"""
|
|
187
|
+
return []
|
|
188
|
+
|
|
189
|
+
def needs_arglist(self) -> bool:
|
|
190
|
+
"""May return true if an empty argument list is to be generated even if
|
|
191
|
+
the document contains none.
|
|
192
|
+
"""
|
|
193
|
+
return False
|
|
194
|
+
|
|
195
|
+
def handle_signature(self, sig: str, signode: desc_signature) -> tuple[str, str]:
|
|
196
|
+
"""Transform a Python signature into RST nodes.
|
|
197
|
+
|
|
198
|
+
Return (fully qualified name of the thing, classname if any).
|
|
199
|
+
|
|
200
|
+
If inside a class, the current class name is handled intelligently:
|
|
201
|
+
* it is stripped from the displayed name if present
|
|
202
|
+
* it is added to the full name (return value) if not present
|
|
203
|
+
"""
|
|
204
|
+
m = py_sig_re.match(sig)
|
|
205
|
+
if m is None:
|
|
206
|
+
raise ValueError
|
|
207
|
+
prefix, name, tp_list, arglist, retann = m.groups()
|
|
208
|
+
|
|
209
|
+
# determine module and class name (if applicable), as well as full name
|
|
210
|
+
modname = self.options.get('module', self.env.ref_context.get('py:module'))
|
|
211
|
+
classname = self.env.ref_context.get('py:class')
|
|
212
|
+
if classname:
|
|
213
|
+
add_module = False
|
|
214
|
+
if prefix and (prefix == classname or
|
|
215
|
+
prefix.startswith(classname + ".")):
|
|
216
|
+
fullname = prefix + name
|
|
217
|
+
# class name is given again in the signature
|
|
218
|
+
prefix = prefix[len(classname):].lstrip('.')
|
|
219
|
+
elif prefix:
|
|
220
|
+
# class name is given in the signature, but different
|
|
221
|
+
# (shouldn't happen)
|
|
222
|
+
fullname = classname + '.' + prefix + name
|
|
223
|
+
else:
|
|
224
|
+
# class name is not given in the signature
|
|
225
|
+
fullname = classname + '.' + name
|
|
226
|
+
else:
|
|
227
|
+
add_module = True
|
|
228
|
+
if prefix:
|
|
229
|
+
classname = prefix.rstrip('.')
|
|
230
|
+
fullname = prefix + name
|
|
231
|
+
else:
|
|
232
|
+
classname = ''
|
|
233
|
+
fullname = name
|
|
234
|
+
|
|
235
|
+
signode['module'] = modname
|
|
236
|
+
signode['class'] = classname
|
|
237
|
+
signode['fullname'] = fullname
|
|
238
|
+
|
|
239
|
+
max_len = (self.env.config.python_maximum_signature_line_length
|
|
240
|
+
or self.env.config.maximum_signature_line_length
|
|
241
|
+
or 0)
|
|
242
|
+
|
|
243
|
+
# determine if the function arguments (without its type parameters)
|
|
244
|
+
# should be formatted on a multiline or not by removing the width of
|
|
245
|
+
# the type parameters list (if any)
|
|
246
|
+
sig_len = len(sig)
|
|
247
|
+
tp_list_span = m.span(3)
|
|
248
|
+
multi_line_parameter_list = (
|
|
249
|
+
'single-line-parameter-list' not in self.options
|
|
250
|
+
and (sig_len - (tp_list_span[1] - tp_list_span[0])) > max_len > 0
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
# determine whether the type parameter list must be wrapped or not
|
|
254
|
+
arglist_span = m.span(4)
|
|
255
|
+
multi_line_type_parameter_list = (
|
|
256
|
+
'single-line-type-parameter-list' not in self.options
|
|
257
|
+
and (sig_len - (arglist_span[1] - arglist_span[0])) > max_len > 0
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
sig_prefix = self.get_signature_prefix(sig)
|
|
261
|
+
if sig_prefix:
|
|
262
|
+
if type(sig_prefix) is str:
|
|
263
|
+
msg = ("Python directive method get_signature_prefix()"
|
|
264
|
+
" must return a list of nodes."
|
|
265
|
+
f" Return value was '{sig_prefix}'.")
|
|
266
|
+
raise TypeError(msg)
|
|
267
|
+
signode += addnodes.desc_annotation(str(sig_prefix), '', *sig_prefix)
|
|
268
|
+
|
|
269
|
+
if prefix:
|
|
270
|
+
signode += addnodes.desc_addname(prefix, prefix)
|
|
271
|
+
elif modname and add_module and self.env.config.add_module_names:
|
|
272
|
+
nodetext = modname + '.'
|
|
273
|
+
signode += addnodes.desc_addname(nodetext, nodetext)
|
|
274
|
+
|
|
275
|
+
signode += addnodes.desc_name(name, name)
|
|
276
|
+
|
|
277
|
+
if tp_list:
|
|
278
|
+
try:
|
|
279
|
+
signode += _parse_type_list(tp_list, self.env, multi_line_type_parameter_list)
|
|
280
|
+
except Exception as exc:
|
|
281
|
+
logger.warning("could not parse tp_list (%r): %s", tp_list, exc,
|
|
282
|
+
location=signode)
|
|
283
|
+
|
|
284
|
+
if arglist:
|
|
285
|
+
try:
|
|
286
|
+
signode += _parse_arglist(arglist, self.env, multi_line_parameter_list)
|
|
287
|
+
except SyntaxError:
|
|
288
|
+
# fallback to parse arglist original parser
|
|
289
|
+
# (this may happen if the argument list is incorrectly used
|
|
290
|
+
# as a list of bases when documenting a class)
|
|
291
|
+
# it supports to represent optional arguments (ex. "func(foo [, bar])")
|
|
292
|
+
_pseudo_parse_arglist(signode, arglist, multi_line_parameter_list)
|
|
293
|
+
except (NotImplementedError, ValueError) as exc:
|
|
294
|
+
# duplicated parameter names raise ValueError and not a SyntaxError
|
|
295
|
+
logger.warning("could not parse arglist (%r): %s", arglist, exc,
|
|
296
|
+
location=signode)
|
|
297
|
+
_pseudo_parse_arglist(signode, arglist, multi_line_parameter_list)
|
|
298
|
+
else:
|
|
299
|
+
if self.needs_arglist():
|
|
300
|
+
# for callables, add an empty parameter list
|
|
301
|
+
signode += addnodes.desc_parameterlist()
|
|
302
|
+
|
|
303
|
+
if retann:
|
|
304
|
+
children = _parse_annotation(retann, self.env)
|
|
305
|
+
signode += addnodes.desc_returns(retann, '', *children)
|
|
306
|
+
|
|
307
|
+
anno = self.options.get('annotation')
|
|
308
|
+
if anno:
|
|
309
|
+
signode += addnodes.desc_annotation(' ' + anno, '',
|
|
310
|
+
addnodes.desc_sig_space(),
|
|
311
|
+
nodes.Text(anno))
|
|
312
|
+
|
|
313
|
+
return fullname, prefix
|
|
314
|
+
|
|
315
|
+
def _object_hierarchy_parts(self, sig_node: desc_signature) -> tuple[str, ...]:
|
|
316
|
+
if 'fullname' not in sig_node:
|
|
317
|
+
return ()
|
|
318
|
+
modname = sig_node.get('module')
|
|
319
|
+
fullname = sig_node['fullname']
|
|
320
|
+
|
|
321
|
+
if modname:
|
|
322
|
+
return (modname, *fullname.split('.'))
|
|
323
|
+
else:
|
|
324
|
+
return tuple(fullname.split('.'))
|
|
325
|
+
|
|
326
|
+
def get_index_text(self, modname: str, name: tuple[str, str]) -> str:
|
|
327
|
+
"""Return the text for the index entry of the object."""
|
|
328
|
+
msg = 'must be implemented in subclasses'
|
|
329
|
+
raise NotImplementedError(msg)
|
|
330
|
+
|
|
331
|
+
def add_target_and_index(self, name_cls: tuple[str, str], sig: str,
|
|
332
|
+
signode: desc_signature) -> None:
|
|
333
|
+
modname = self.options.get('module', self.env.ref_context.get('py:module'))
|
|
334
|
+
fullname = (modname + '.' if modname else '') + name_cls[0]
|
|
335
|
+
node_id = make_id(self.env, self.state.document, '', fullname)
|
|
336
|
+
signode['ids'].append(node_id)
|
|
337
|
+
self.state.document.note_explicit_target(signode)
|
|
338
|
+
|
|
339
|
+
domain = self.env.domains['py']
|
|
340
|
+
domain.note_object(fullname, self.objtype, node_id, location=signode)
|
|
341
|
+
|
|
342
|
+
canonical_name = self.options.get('canonical')
|
|
343
|
+
if canonical_name:
|
|
344
|
+
domain.note_object(canonical_name, self.objtype, node_id, aliased=True,
|
|
345
|
+
location=signode)
|
|
346
|
+
|
|
347
|
+
if 'no-index-entry' not in self.options:
|
|
348
|
+
indextext = self.get_index_text(modname, name_cls)
|
|
349
|
+
if indextext:
|
|
350
|
+
self.indexnode['entries'].append(('single', indextext, node_id, '', None))
|
|
351
|
+
|
|
352
|
+
def before_content(self) -> None:
|
|
353
|
+
"""Handle object nesting before content
|
|
354
|
+
|
|
355
|
+
:py:class:`PyObject` represents Python language constructs. For
|
|
356
|
+
constructs that are nestable, such as a Python classes, this method will
|
|
357
|
+
build up a stack of the nesting hierarchy so that it can be later
|
|
358
|
+
de-nested correctly, in :py:meth:`after_content`.
|
|
359
|
+
|
|
360
|
+
For constructs that aren't nestable, the stack is bypassed, and instead
|
|
361
|
+
only the most recent object is tracked. This object prefix name will be
|
|
362
|
+
removed with :py:meth:`after_content`.
|
|
363
|
+
"""
|
|
364
|
+
prefix = None
|
|
365
|
+
if self.names:
|
|
366
|
+
# fullname and name_prefix come from the `handle_signature` method.
|
|
367
|
+
# fullname represents the full object name that is constructed using
|
|
368
|
+
# object nesting and explicit prefixes. `name_prefix` is the
|
|
369
|
+
# explicit prefix given in a signature
|
|
370
|
+
(fullname, name_prefix) = self.names[-1]
|
|
371
|
+
if self.allow_nesting:
|
|
372
|
+
prefix = fullname
|
|
373
|
+
elif name_prefix:
|
|
374
|
+
prefix = name_prefix.strip('.')
|
|
375
|
+
if prefix:
|
|
376
|
+
self.env.ref_context['py:class'] = prefix
|
|
377
|
+
if self.allow_nesting:
|
|
378
|
+
classes = self.env.ref_context.setdefault('py:classes', [])
|
|
379
|
+
classes.append(prefix)
|
|
380
|
+
if 'module' in self.options:
|
|
381
|
+
modules = self.env.ref_context.setdefault('py:modules', [])
|
|
382
|
+
modules.append(self.env.ref_context.get('py:module'))
|
|
383
|
+
self.env.ref_context['py:module'] = self.options['module']
|
|
384
|
+
|
|
385
|
+
def after_content(self) -> None:
|
|
386
|
+
"""Handle object de-nesting after content
|
|
387
|
+
|
|
388
|
+
If this class is a nestable object, removing the last nested class prefix
|
|
389
|
+
ends further nesting in the object.
|
|
390
|
+
|
|
391
|
+
If this class is not a nestable object, the list of classes should not
|
|
392
|
+
be altered as we didn't affect the nesting levels in
|
|
393
|
+
:py:meth:`before_content`.
|
|
394
|
+
"""
|
|
395
|
+
classes = self.env.ref_context.setdefault('py:classes', [])
|
|
396
|
+
if self.allow_nesting:
|
|
397
|
+
with contextlib.suppress(IndexError):
|
|
398
|
+
classes.pop()
|
|
399
|
+
|
|
400
|
+
self.env.ref_context['py:class'] = (classes[-1] if len(classes) > 0
|
|
401
|
+
else None)
|
|
402
|
+
if 'module' in self.options:
|
|
403
|
+
modules = self.env.ref_context.setdefault('py:modules', [])
|
|
404
|
+
if modules:
|
|
405
|
+
self.env.ref_context['py:module'] = modules.pop()
|
|
406
|
+
else:
|
|
407
|
+
self.env.ref_context.pop('py:module')
|
|
408
|
+
|
|
409
|
+
def _toc_entry_name(self, sig_node: desc_signature) -> str:
|
|
410
|
+
if not sig_node.get('_toc_parts'):
|
|
411
|
+
return ''
|
|
412
|
+
|
|
413
|
+
config = self.env.app.config
|
|
414
|
+
objtype = sig_node.parent.get('objtype')
|
|
415
|
+
if config.add_function_parentheses and objtype in {'function', 'method'}:
|
|
416
|
+
parens = '()'
|
|
417
|
+
else:
|
|
418
|
+
parens = ''
|
|
419
|
+
*parents, name = sig_node['_toc_parts']
|
|
420
|
+
if config.toc_object_entries_show_parents == 'domain':
|
|
421
|
+
return sig_node.get('fullname', name) + parens
|
|
422
|
+
if config.toc_object_entries_show_parents == 'hide':
|
|
423
|
+
return name + parens
|
|
424
|
+
if config.toc_object_entries_show_parents == 'all':
|
|
425
|
+
return '.'.join([*parents, name + parens])
|
|
426
|
+
return ''
|
sphinx/domains/rst.py
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import re
|
|
6
|
-
from typing import TYPE_CHECKING, Any, cast
|
|
6
|
+
from typing import TYPE_CHECKING, Any, ClassVar, cast
|
|
7
7
|
|
|
8
8
|
from docutils.parsers.rst import directives
|
|
9
9
|
|
|
@@ -24,7 +24,7 @@ if TYPE_CHECKING:
|
|
|
24
24
|
from sphinx.application import Sphinx
|
|
25
25
|
from sphinx.builders import Builder
|
|
26
26
|
from sphinx.environment import BuildEnvironment
|
|
27
|
-
from sphinx.util.typing import OptionSpec
|
|
27
|
+
from sphinx.util.typing import ExtensionMetadata, OptionSpec
|
|
28
28
|
|
|
29
29
|
logger = logging.getLogger(__name__)
|
|
30
30
|
|
|
@@ -35,7 +35,8 @@ class ReSTMarkup(ObjectDescription[str]):
|
|
|
35
35
|
"""
|
|
36
36
|
Description of generic reST markup.
|
|
37
37
|
"""
|
|
38
|
-
|
|
38
|
+
|
|
39
|
+
option_spec: ClassVar[OptionSpec] = {
|
|
39
40
|
'no-index': directives.flag,
|
|
40
41
|
'no-index-entry': directives.flag,
|
|
41
42
|
'no-contents-entry': directives.flag,
|
|
@@ -112,6 +113,7 @@ class ReSTDirective(ReSTMarkup):
|
|
|
112
113
|
"""
|
|
113
114
|
Description of a reST directive.
|
|
114
115
|
"""
|
|
116
|
+
|
|
115
117
|
def handle_signature(self, sig: str, signode: desc_signature) -> str:
|
|
116
118
|
name, args = parse_directive(sig)
|
|
117
119
|
desc_name = f'.. {name}::'
|
|
@@ -139,7 +141,8 @@ class ReSTDirectiveOption(ReSTMarkup):
|
|
|
139
141
|
"""
|
|
140
142
|
Description of an option for reST directive.
|
|
141
143
|
"""
|
|
142
|
-
|
|
144
|
+
|
|
145
|
+
option_spec: ClassVar[OptionSpec] = ReSTMarkup.option_spec.copy()
|
|
143
146
|
option_spec.update({
|
|
144
147
|
'type': directives.unchanged,
|
|
145
148
|
})
|
|
@@ -165,8 +168,8 @@ class ReSTDirectiveOption(ReSTMarkup):
|
|
|
165
168
|
|
|
166
169
|
directive_name = self.current_directive
|
|
167
170
|
if directive_name:
|
|
168
|
-
prefix = '
|
|
169
|
-
objname = ':'
|
|
171
|
+
prefix = f'{self.objtype}-{directive_name}'
|
|
172
|
+
objname = f'{directive_name}:{name}'
|
|
170
173
|
else:
|
|
171
174
|
prefix = self.objtype
|
|
172
175
|
objname = name
|
|
@@ -199,6 +202,7 @@ class ReSTRole(ReSTMarkup):
|
|
|
199
202
|
"""
|
|
200
203
|
Description of a reST role.
|
|
201
204
|
"""
|
|
205
|
+
|
|
202
206
|
def handle_signature(self, sig: str, signode: desc_signature) -> str:
|
|
203
207
|
desc_name = f':{sig}:'
|
|
204
208
|
signode['fullname'] = sig.strip()
|
|
@@ -211,6 +215,7 @@ class ReSTRole(ReSTMarkup):
|
|
|
211
215
|
|
|
212
216
|
class ReSTDomain(Domain):
|
|
213
217
|
"""ReStructuredText domain."""
|
|
218
|
+
|
|
214
219
|
name = 'rst'
|
|
215
220
|
label = 'reStructuredText'
|
|
216
221
|
|
|
@@ -288,7 +293,7 @@ class ReSTDomain(Domain):
|
|
|
288
293
|
yield name, name, typ, docname, node_id, 1
|
|
289
294
|
|
|
290
295
|
|
|
291
|
-
def setup(app: Sphinx) ->
|
|
296
|
+
def setup(app: Sphinx) -> ExtensionMetadata:
|
|
292
297
|
app.add_domain(ReSTDomain)
|
|
293
298
|
|
|
294
299
|
return {
|
|
@@ -4,7 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import re
|
|
6
6
|
from copy import copy
|
|
7
|
-
from typing import TYPE_CHECKING, Any, Callable, Final, cast
|
|
7
|
+
from typing import TYPE_CHECKING, Any, Callable, ClassVar, Final, cast
|
|
8
8
|
|
|
9
9
|
from docutils import nodes
|
|
10
10
|
from docutils.nodes import Element, Node, system_message
|
|
@@ -27,14 +27,14 @@ if TYPE_CHECKING:
|
|
|
27
27
|
from sphinx.application import Sphinx
|
|
28
28
|
from sphinx.builders import Builder
|
|
29
29
|
from sphinx.environment import BuildEnvironment
|
|
30
|
-
from sphinx.util.typing import OptionSpec, RoleFunction
|
|
30
|
+
from sphinx.util.typing import ExtensionMetadata, OptionSpec, RoleFunction
|
|
31
31
|
|
|
32
32
|
logger = logging.getLogger(__name__)
|
|
33
33
|
|
|
34
34
|
# RE for option descriptions
|
|
35
35
|
option_desc_re = re.compile(r'((?:/|--|-|\+)?[^\s=]+)(=?\s*.*)')
|
|
36
36
|
# RE for grammar tokens
|
|
37
|
-
token_re = re.compile(r'`((
|
|
37
|
+
token_re = re.compile(r'`((~?[\w-]*:)?\w+)`')
|
|
38
38
|
|
|
39
39
|
samp_role = EmphasizedLiteral()
|
|
40
40
|
|
|
@@ -43,6 +43,7 @@ class GenericObject(ObjectDescription[str]):
|
|
|
43
43
|
"""
|
|
44
44
|
A generic x-ref directive registered with Sphinx.add_object_type().
|
|
45
45
|
"""
|
|
46
|
+
|
|
46
47
|
indextemplate: str = ''
|
|
47
48
|
parse_node: Callable[[BuildEnvironment, str, desc_signature], str] | None = None
|
|
48
49
|
|
|
@@ -104,13 +105,14 @@ class Target(SphinxDirective):
|
|
|
104
105
|
"""
|
|
105
106
|
Generic target for user-defined cross-reference types.
|
|
106
107
|
"""
|
|
108
|
+
|
|
107
109
|
indextemplate = ''
|
|
108
110
|
|
|
109
111
|
has_content = False
|
|
110
112
|
required_arguments = 1
|
|
111
113
|
optional_arguments = 0
|
|
112
114
|
final_argument_whitespace = True
|
|
113
|
-
option_spec: OptionSpec = {}
|
|
115
|
+
option_spec: ClassVar[OptionSpec] = {}
|
|
114
116
|
|
|
115
117
|
def run(self) -> list[Node]:
|
|
116
118
|
# normalize whitespace in fullname like XRefRole does
|
|
@@ -204,7 +206,7 @@ class Cmdoption(ObjectDescription[str]):
|
|
|
204
206
|
|
|
205
207
|
def add_target_and_index(self, firstname: str, sig: str, signode: desc_signature) -> None:
|
|
206
208
|
currprogram = self.env.ref_context.get('std:program')
|
|
207
|
-
for optname in signode.get('allnames', []):
|
|
209
|
+
for optname in signode.get('allnames', []): # type: ignore[var-annotated]
|
|
208
210
|
prefixes = ['cmdoption']
|
|
209
211
|
if currprogram:
|
|
210
212
|
prefixes.append(currprogram)
|
|
@@ -226,8 +228,8 @@ class Cmdoption(ObjectDescription[str]):
|
|
|
226
228
|
descr = _('%s command line option') % currprogram
|
|
227
229
|
else:
|
|
228
230
|
descr = _('command line option')
|
|
229
|
-
for option in signode.get('allnames', []):
|
|
230
|
-
entry = '; '
|
|
231
|
+
for option in signode.get('allnames', []): # type: ignore[var-annotated]
|
|
232
|
+
entry = f'{descr}; {option}'
|
|
231
233
|
self.indexnode['entries'].append(('pair', entry, signode['ids'][0], '', None))
|
|
232
234
|
|
|
233
235
|
|
|
@@ -240,7 +242,7 @@ class Program(SphinxDirective):
|
|
|
240
242
|
required_arguments = 1
|
|
241
243
|
optional_arguments = 0
|
|
242
244
|
final_argument_whitespace = True
|
|
243
|
-
option_spec: OptionSpec = {}
|
|
245
|
+
option_spec: ClassVar[OptionSpec] = {}
|
|
244
246
|
|
|
245
247
|
def run(self) -> list[Node]:
|
|
246
248
|
program = ws_re.sub('-', self.arguments[0].strip())
|
|
@@ -260,7 +262,7 @@ class OptionXRefRole(XRefRole):
|
|
|
260
262
|
|
|
261
263
|
def split_term_classifiers(line: str) -> list[str | None]:
|
|
262
264
|
# split line into a term and classifiers. if no classifier, None is used..
|
|
263
|
-
parts: list[str | None] = re.split(' +: +', line)
|
|
265
|
+
parts: list[str | None] = [*re.split(' +: +', line), None]
|
|
264
266
|
return parts
|
|
265
267
|
|
|
266
268
|
|
|
@@ -304,7 +306,7 @@ class Glossary(SphinxDirective):
|
|
|
304
306
|
required_arguments = 0
|
|
305
307
|
optional_arguments = 0
|
|
306
308
|
final_argument_whitespace = False
|
|
307
|
-
option_spec: OptionSpec = {
|
|
309
|
+
option_spec: ClassVar[OptionSpec] = {
|
|
308
310
|
'sorted': directives.flag,
|
|
309
311
|
}
|
|
310
312
|
|
|
@@ -383,7 +385,7 @@ class Glossary(SphinxDirective):
|
|
|
383
385
|
parts = split_term_classifiers(line)
|
|
384
386
|
# parse the term with inline markup
|
|
385
387
|
# classifiers (parts[1:]) will not be shown on doctree
|
|
386
|
-
textnodes, sysmsg = self.state.inline_text(parts[0],
|
|
388
|
+
textnodes, sysmsg = self.state.inline_text(parts[0],
|
|
387
389
|
lineno)
|
|
388
390
|
|
|
389
391
|
# use first classifier as a index key
|
|
@@ -406,7 +408,7 @@ class Glossary(SphinxDirective):
|
|
|
406
408
|
dlist = nodes.definition_list('', *items)
|
|
407
409
|
dlist['classes'].append('glossary')
|
|
408
410
|
node += dlist
|
|
409
|
-
return messages
|
|
411
|
+
return [*messages, node]
|
|
410
412
|
|
|
411
413
|
|
|
412
414
|
def token_xrefs(text: str, productionGroup: str = '') -> list[Node]:
|
|
@@ -451,7 +453,7 @@ class ProductionList(SphinxDirective):
|
|
|
451
453
|
required_arguments = 1
|
|
452
454
|
optional_arguments = 0
|
|
453
455
|
final_argument_whitespace = True
|
|
454
|
-
option_spec: OptionSpec = {}
|
|
456
|
+
option_spec: ClassVar[OptionSpec] = {}
|
|
455
457
|
|
|
456
458
|
def run(self) -> list[Node]:
|
|
457
459
|
domain = cast(StandardDomain, self.env.get_domain('std'))
|
|
@@ -1000,7 +1002,7 @@ class StandardDomain(Domain):
|
|
|
1000
1002
|
yield (doc, clean_astext(self.env.titles[doc]), 'doc', doc, '', -1)
|
|
1001
1003
|
for (prog, option), info in self.progoptions.items():
|
|
1002
1004
|
if prog:
|
|
1003
|
-
fullname =
|
|
1005
|
+
fullname = f'{prog}.{option}'
|
|
1004
1006
|
yield (fullname, fullname, 'cmdoption', info[0], info[1], 1)
|
|
1005
1007
|
else:
|
|
1006
1008
|
yield (option, option, 'cmdoption', info[0], info[1], 1)
|
|
@@ -1089,7 +1091,8 @@ class StandardDomain(Domain):
|
|
|
1089
1091
|
command.insert(0, progname)
|
|
1090
1092
|
option = command.pop()
|
|
1091
1093
|
if command:
|
|
1092
|
-
|
|
1094
|
+
command_str = '-'.join(command)
|
|
1095
|
+
return f'{command_str}.{option}'
|
|
1093
1096
|
else:
|
|
1094
1097
|
return None
|
|
1095
1098
|
else:
|
|
@@ -1111,7 +1114,7 @@ def warn_missing_reference(app: Sphinx, domain: Domain, node: pending_xref,
|
|
|
1111
1114
|
return True
|
|
1112
1115
|
|
|
1113
1116
|
|
|
1114
|
-
def setup(app: Sphinx) ->
|
|
1117
|
+
def setup(app: Sphinx) -> ExtensionMetadata:
|
|
1115
1118
|
app.add_domain(StandardDomain)
|
|
1116
1119
|
app.connect('warn-missing-reference', warn_missing_reference)
|
|
1117
1120
|
|