Sphinx 8.1.2__py3-none-any.whl → 8.2.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 +8 -4
- sphinx/__main__.py +2 -0
- sphinx/_cli/__init__.py +2 -5
- sphinx/_cli/util/colour.py +34 -11
- sphinx/_cli/util/errors.py +128 -61
- sphinx/addnodes.py +51 -35
- sphinx/application.py +362 -230
- sphinx/builders/__init__.py +87 -64
- sphinx/builders/_epub_base.py +65 -56
- sphinx/builders/changes.py +17 -23
- sphinx/builders/dirhtml.py +8 -13
- sphinx/builders/epub3.py +70 -38
- sphinx/builders/gettext.py +93 -73
- sphinx/builders/html/__init__.py +240 -186
- sphinx/builders/html/_assets.py +9 -2
- sphinx/builders/html/_build_info.py +3 -0
- sphinx/builders/latex/__init__.py +64 -54
- sphinx/builders/latex/constants.py +14 -11
- sphinx/builders/latex/nodes.py +2 -0
- sphinx/builders/latex/theming.py +8 -9
- sphinx/builders/latex/transforms.py +7 -5
- sphinx/builders/linkcheck.py +193 -149
- sphinx/builders/manpage.py +17 -17
- sphinx/builders/singlehtml.py +28 -16
- sphinx/builders/texinfo.py +28 -21
- sphinx/builders/text.py +10 -15
- sphinx/builders/xml.py +10 -19
- sphinx/cmd/build.py +49 -119
- sphinx/cmd/make_mode.py +35 -31
- sphinx/cmd/quickstart.py +78 -62
- sphinx/config.py +265 -163
- sphinx/directives/__init__.py +51 -54
- sphinx/directives/admonitions.py +107 -0
- sphinx/directives/code.py +24 -19
- sphinx/directives/other.py +21 -42
- sphinx/directives/patches.py +28 -16
- sphinx/domains/__init__.py +54 -31
- sphinx/domains/_domains_container.py +22 -17
- sphinx/domains/_index.py +5 -8
- sphinx/domains/c/__init__.py +366 -245
- sphinx/domains/c/_ast.py +378 -256
- sphinx/domains/c/_ids.py +89 -31
- sphinx/domains/c/_parser.py +283 -214
- sphinx/domains/c/_symbol.py +269 -198
- sphinx/domains/changeset.py +39 -24
- sphinx/domains/citation.py +54 -24
- sphinx/domains/cpp/__init__.py +517 -362
- sphinx/domains/cpp/_ast.py +999 -682
- sphinx/domains/cpp/_ids.py +133 -65
- sphinx/domains/cpp/_parser.py +746 -588
- sphinx/domains/cpp/_symbol.py +692 -489
- sphinx/domains/index.py +10 -8
- sphinx/domains/javascript.py +152 -74
- sphinx/domains/math.py +50 -40
- sphinx/domains/python/__init__.py +402 -211
- sphinx/domains/python/_annotations.py +134 -61
- sphinx/domains/python/_object.py +155 -68
- sphinx/domains/rst.py +94 -49
- sphinx/domains/std/__init__.py +510 -249
- sphinx/environment/__init__.py +345 -61
- sphinx/environment/adapters/asset.py +7 -1
- sphinx/environment/adapters/indexentries.py +15 -20
- sphinx/environment/adapters/toctree.py +19 -9
- sphinx/environment/collectors/__init__.py +3 -1
- sphinx/environment/collectors/asset.py +18 -15
- sphinx/environment/collectors/dependencies.py +8 -10
- sphinx/environment/collectors/metadata.py +6 -4
- sphinx/environment/collectors/title.py +3 -1
- sphinx/environment/collectors/toctree.py +4 -4
- sphinx/errors.py +1 -3
- sphinx/events.py +4 -4
- sphinx/ext/apidoc/__init__.py +66 -0
- sphinx/ext/apidoc/__main__.py +9 -0
- sphinx/ext/apidoc/_cli.py +356 -0
- sphinx/ext/apidoc/_extension.py +262 -0
- sphinx/ext/apidoc/_generate.py +356 -0
- sphinx/ext/apidoc/_shared.py +99 -0
- sphinx/ext/autodoc/__init__.py +837 -483
- sphinx/ext/autodoc/directive.py +57 -21
- sphinx/ext/autodoc/importer.py +184 -67
- sphinx/ext/autodoc/mock.py +25 -10
- sphinx/ext/autodoc/preserve_defaults.py +17 -9
- sphinx/ext/autodoc/type_comment.py +56 -29
- sphinx/ext/autodoc/typehints.py +49 -26
- sphinx/ext/autosectionlabel.py +28 -11
- sphinx/ext/autosummary/__init__.py +281 -142
- sphinx/ext/autosummary/generate.py +121 -51
- sphinx/ext/coverage.py +152 -91
- sphinx/ext/doctest.py +169 -101
- sphinx/ext/duration.py +12 -6
- sphinx/ext/extlinks.py +33 -21
- sphinx/ext/githubpages.py +8 -8
- sphinx/ext/graphviz.py +175 -109
- sphinx/ext/ifconfig.py +11 -6
- sphinx/ext/imgconverter.py +48 -25
- sphinx/ext/imgmath.py +127 -97
- sphinx/ext/inheritance_diagram.py +177 -103
- sphinx/ext/intersphinx/__init__.py +22 -13
- sphinx/ext/intersphinx/__main__.py +3 -1
- sphinx/ext/intersphinx/_cli.py +18 -14
- sphinx/ext/intersphinx/_load.py +91 -82
- sphinx/ext/intersphinx/_resolve.py +108 -74
- sphinx/ext/intersphinx/_shared.py +2 -2
- sphinx/ext/linkcode.py +28 -12
- sphinx/ext/mathjax.py +60 -29
- sphinx/ext/napoleon/__init__.py +19 -7
- sphinx/ext/napoleon/docstring.py +229 -231
- sphinx/ext/todo.py +44 -49
- sphinx/ext/viewcode.py +105 -57
- sphinx/extension.py +3 -1
- sphinx/highlighting.py +13 -7
- sphinx/io.py +9 -13
- sphinx/jinja2glue.py +29 -26
- sphinx/locale/__init__.py +8 -9
- sphinx/locale/ar/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ar/LC_MESSAGES/sphinx.po +2155 -2050
- sphinx/locale/bg/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/bg/LC_MESSAGES/sphinx.po +2045 -1940
- sphinx/locale/bn/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/bn/LC_MESSAGES/sphinx.po +2175 -2070
- sphinx/locale/ca/LC_MESSAGES/sphinx.js +3 -3
- sphinx/locale/ca/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ca/LC_MESSAGES/sphinx.po +2690 -2585
- sphinx/locale/ca@valencia/LC_MESSAGES/sphinx.js +63 -0
- sphinx/locale/ca@valencia/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ca@valencia/LC_MESSAGES/sphinx.po +4216 -0
- sphinx/locale/cak/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cak/LC_MESSAGES/sphinx.po +2096 -1991
- sphinx/locale/cs/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cs/LC_MESSAGES/sphinx.po +2248 -2143
- sphinx/locale/cy/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cy/LC_MESSAGES/sphinx.po +2201 -2096
- sphinx/locale/da/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/da/LC_MESSAGES/sphinx.po +2282 -2177
- sphinx/locale/de/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/de/LC_MESSAGES/sphinx.po +2261 -2156
- sphinx/locale/de_DE/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/de_DE/LC_MESSAGES/sphinx.po +2045 -1940
- sphinx/locale/el/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/el/LC_MESSAGES/sphinx.po +2604 -2499
- sphinx/locale/en_DE/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_DE/LC_MESSAGES/sphinx.po +2045 -1940
- sphinx/locale/en_FR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_FR/LC_MESSAGES/sphinx.po +2045 -1940
- sphinx/locale/en_GB/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_GB/LC_MESSAGES/sphinx.po +2631 -2526
- sphinx/locale/en_HK/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_HK/LC_MESSAGES/sphinx.po +2045 -1940
- sphinx/locale/eo/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/eo/LC_MESSAGES/sphinx.po +2078 -1973
- sphinx/locale/es/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/es/LC_MESSAGES/sphinx.po +2633 -2528
- sphinx/locale/es_CO/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/es_CO/LC_MESSAGES/sphinx.po +2045 -1940
- sphinx/locale/et/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/et/LC_MESSAGES/sphinx.po +2449 -2344
- sphinx/locale/eu/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/eu/LC_MESSAGES/sphinx.po +2241 -2136
- sphinx/locale/fa/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fa/LC_MESSAGES/sphinx.po +504 -500
- sphinx/locale/fi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fi/LC_MESSAGES/sphinx.po +499 -495
- sphinx/locale/fr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fr/LC_MESSAGES/sphinx.po +513 -509
- sphinx/locale/fr_FR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fr_FR/LC_MESSAGES/sphinx.po +499 -495
- sphinx/locale/gl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/gl/LC_MESSAGES/sphinx.po +2644 -2539
- sphinx/locale/he/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/he/LC_MESSAGES/sphinx.po +499 -495
- sphinx/locale/hi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hi/LC_MESSAGES/sphinx.po +504 -500
- sphinx/locale/hi_IN/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hi_IN/LC_MESSAGES/sphinx.po +499 -495
- sphinx/locale/hr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hr/LC_MESSAGES/sphinx.po +501 -497
- sphinx/locale/hu/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hu/LC_MESSAGES/sphinx.po +499 -495
- sphinx/locale/id/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/id/LC_MESSAGES/sphinx.po +2609 -2504
- sphinx/locale/is/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/is/LC_MESSAGES/sphinx.po +499 -495
- sphinx/locale/it/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/it/LC_MESSAGES/sphinx.po +2265 -2160
- sphinx/locale/ja/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ja/LC_MESSAGES/sphinx.po +2621 -2516
- sphinx/locale/ka/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ka/LC_MESSAGES/sphinx.po +2567 -2462
- sphinx/locale/ko/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ko/LC_MESSAGES/sphinx.po +2631 -2526
- sphinx/locale/lt/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/lt/LC_MESSAGES/sphinx.po +2214 -2109
- sphinx/locale/lv/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/lv/LC_MESSAGES/sphinx.po +2218 -2113
- sphinx/locale/mk/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/mk/LC_MESSAGES/sphinx.po +2088 -1983
- sphinx/locale/nb_NO/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po +2247 -2142
- sphinx/locale/ne/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ne/LC_MESSAGES/sphinx.po +2227 -2122
- sphinx/locale/nl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/nl/LC_MESSAGES/sphinx.po +2316 -2211
- sphinx/locale/pl/LC_MESSAGES/sphinx.js +2 -2
- sphinx/locale/pl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pl/LC_MESSAGES/sphinx.po +2442 -2336
- sphinx/locale/pt/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt/LC_MESSAGES/sphinx.po +2045 -1940
- sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po +2657 -2552
- sphinx/locale/pt_PT/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt_PT/LC_MESSAGES/sphinx.po +2243 -2138
- sphinx/locale/ro/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ro/LC_MESSAGES/sphinx.po +2244 -2139
- sphinx/locale/ru/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/ru/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ru/LC_MESSAGES/sphinx.po +2660 -2555
- sphinx/locale/si/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/si/LC_MESSAGES/sphinx.po +2134 -2029
- sphinx/locale/sk/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sk/LC_MESSAGES/sphinx.po +2614 -2509
- sphinx/locale/sl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sl/LC_MESSAGES/sphinx.po +2167 -2062
- sphinx/locale/sphinx.pot +2069 -1964
- sphinx/locale/sq/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sq/LC_MESSAGES/sphinx.po +2661 -2556
- sphinx/locale/sr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sr/LC_MESSAGES/sphinx.po +2213 -2108
- sphinx/locale/sv/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sv/LC_MESSAGES/sphinx.po +2229 -2124
- sphinx/locale/te/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/te/LC_MESSAGES/sphinx.po +2045 -1940
- sphinx/locale/tr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/tr/LC_MESSAGES/sphinx.po +2608 -2503
- sphinx/locale/uk_UA/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po +2167 -2062
- sphinx/locale/ur/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ur/LC_MESSAGES/sphinx.po +2045 -1940
- sphinx/locale/vi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/vi/LC_MESSAGES/sphinx.po +2204 -2099
- sphinx/locale/yue/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/yue/LC_MESSAGES/sphinx.po +2045 -1940
- sphinx/locale/zh_HK/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_HK/LC_MESSAGES/sphinx.po +2045 -1940
- sphinx/locale/zh_TW/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po +2659 -2554
- sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.po +2045 -1940
- sphinx/parsers.py +8 -7
- sphinx/project.py +2 -2
- sphinx/pycode/__init__.py +31 -21
- sphinx/pycode/ast.py +6 -3
- sphinx/pycode/parser.py +14 -8
- sphinx/pygments_styles.py +4 -5
- sphinx/registry.py +192 -92
- sphinx/roles.py +58 -7
- sphinx/search/__init__.py +75 -54
- sphinx/search/en.py +11 -13
- sphinx/search/fi.py +1 -1
- sphinx/search/ja.py +8 -6
- sphinx/search/nl.py +1 -1
- sphinx/search/zh.py +19 -21
- sphinx/testing/fixtures.py +26 -29
- sphinx/testing/path.py +26 -62
- sphinx/testing/restructuredtext.py +14 -8
- sphinx/testing/util.py +21 -19
- sphinx/texinputs/make.bat.jinja +50 -50
- sphinx/texinputs/sphinx.sty +4 -3
- sphinx/texinputs/sphinxlatexadmonitions.sty +1 -1
- sphinx/texinputs/sphinxlatexobjects.sty +29 -10
- sphinx/themes/basic/static/searchtools.js +8 -5
- sphinx/theming.py +49 -61
- sphinx/transforms/__init__.py +17 -38
- sphinx/transforms/compact_bullet_list.py +5 -3
- sphinx/transforms/i18n.py +8 -21
- sphinx/transforms/post_transforms/__init__.py +142 -93
- sphinx/transforms/post_transforms/code.py +5 -5
- sphinx/transforms/post_transforms/images.py +28 -24
- sphinx/transforms/references.py +3 -1
- sphinx/util/__init__.py +109 -60
- sphinx/util/_files.py +39 -23
- sphinx/util/_importer.py +4 -1
- sphinx/util/_inventory_file_reader.py +76 -0
- sphinx/util/_io.py +2 -2
- sphinx/util/_lines.py +6 -3
- sphinx/util/_pathlib.py +40 -2
- sphinx/util/build_phase.py +2 -0
- sphinx/util/cfamily.py +19 -14
- sphinx/util/console.py +44 -179
- sphinx/util/display.py +9 -10
- sphinx/util/docfields.py +140 -122
- sphinx/util/docstrings.py +1 -1
- sphinx/util/docutils.py +118 -77
- sphinx/util/fileutil.py +25 -26
- sphinx/util/http_date.py +2 -0
- sphinx/util/i18n.py +77 -64
- sphinx/util/images.py +8 -6
- sphinx/util/inspect.py +147 -38
- sphinx/util/inventory.py +215 -116
- sphinx/util/logging.py +33 -33
- sphinx/util/matching.py +12 -4
- sphinx/util/nodes.py +18 -13
- sphinx/util/osutil.py +38 -39
- sphinx/util/parallel.py +22 -13
- sphinx/util/parsing.py +2 -1
- sphinx/util/png.py +6 -2
- sphinx/util/requests.py +33 -2
- sphinx/util/rst.py +3 -2
- sphinx/util/tags.py +1 -1
- sphinx/util/template.py +18 -10
- sphinx/util/texescape.py +8 -6
- sphinx/util/typing.py +148 -122
- sphinx/versioning.py +3 -3
- sphinx/writers/html.py +3 -1
- sphinx/writers/html5.py +63 -52
- sphinx/writers/latex.py +83 -67
- sphinx/writers/manpage.py +19 -38
- sphinx/writers/texinfo.py +47 -47
- sphinx/writers/text.py +50 -32
- sphinx/writers/xml.py +11 -8
- {sphinx-8.1.2.dist-info → sphinx-8.2.0.dist-info}/LICENSE.rst +1 -1
- {sphinx-8.1.2.dist-info → sphinx-8.2.0.dist-info}/METADATA +25 -15
- sphinx-8.2.0.dist-info/RECORD +606 -0
- {sphinx-8.1.2.dist-info → sphinx-8.2.0.dist-info}/WHEEL +1 -1
- sphinx/builders/html/transforms.py +0 -90
- sphinx/ext/apidoc.py +0 -721
- sphinx/util/exceptions.py +0 -74
- sphinx-8.1.2.dist-info/RECORD +0 -598
- {sphinx-8.1.2.dist-info → sphinx-8.2.0.dist-info}/entry_points.txt +0 -0
sphinx/domains/python/_object.py
CHANGED
|
@@ -2,13 +2,13 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import contextlib
|
|
4
4
|
import re
|
|
5
|
-
from typing import TYPE_CHECKING
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
6
|
|
|
7
7
|
from docutils import nodes
|
|
8
8
|
from docutils.parsers.rst import directives
|
|
9
9
|
|
|
10
10
|
from sphinx import addnodes
|
|
11
|
-
from sphinx.addnodes import
|
|
11
|
+
from sphinx.addnodes import pending_xref, pending_xref_condition
|
|
12
12
|
from sphinx.directives import ObjectDescription
|
|
13
13
|
from sphinx.domains.python._annotations import (
|
|
14
14
|
_parse_annotation,
|
|
@@ -25,9 +25,13 @@ from sphinx.util.nodes import (
|
|
|
25
25
|
)
|
|
26
26
|
|
|
27
27
|
if TYPE_CHECKING:
|
|
28
|
+
from collections.abc import Sequence
|
|
29
|
+
from typing import ClassVar
|
|
30
|
+
|
|
28
31
|
from docutils.nodes import Node
|
|
29
32
|
from docutils.parsers.rst.states import Inliner
|
|
30
33
|
|
|
34
|
+
from sphinx.addnodes import desc_signature
|
|
31
35
|
from sphinx.environment import BuildEnvironment
|
|
32
36
|
from sphinx.util.typing import OptionSpec, TextlikeNode
|
|
33
37
|
|
|
@@ -35,13 +39,15 @@ logger = logging.getLogger(__name__)
|
|
|
35
39
|
|
|
36
40
|
# REs for Python signatures
|
|
37
41
|
py_sig_re = re.compile(
|
|
38
|
-
r
|
|
42
|
+
r"""^ ([\w.]*\.)? # class name(s)
|
|
39
43
|
(\w+) \s* # thing name
|
|
40
|
-
(?: \[\s*(
|
|
44
|
+
(?: \[\s*(.*?)\s*])? # optional: type parameters list
|
|
41
45
|
(?: \(\s*(.*)\s*\) # optional: arguments
|
|
42
46
|
(?:\s* -> \s* (.*))? # return annotation
|
|
43
47
|
)? $ # and nothing more
|
|
44
|
-
|
|
48
|
+
""",
|
|
49
|
+
re.VERBOSE,
|
|
50
|
+
)
|
|
45
51
|
|
|
46
52
|
|
|
47
53
|
# This override allows our inline type specifiers to behave like :class: link
|
|
@@ -60,9 +66,16 @@ class PyXrefMixin:
|
|
|
60
66
|
) -> Node:
|
|
61
67
|
# we use inliner=None to make sure we get the old behaviour with a single
|
|
62
68
|
# pending_xref node
|
|
63
|
-
result = super().make_xref(
|
|
64
|
-
|
|
65
|
-
|
|
69
|
+
result = super().make_xref( # type: ignore[misc]
|
|
70
|
+
rolename,
|
|
71
|
+
domain,
|
|
72
|
+
target,
|
|
73
|
+
innernode,
|
|
74
|
+
contnode,
|
|
75
|
+
env,
|
|
76
|
+
inliner=None,
|
|
77
|
+
location=None,
|
|
78
|
+
)
|
|
66
79
|
if isinstance(result, pending_xref):
|
|
67
80
|
assert env is not None
|
|
68
81
|
result['refspecific'] = True
|
|
@@ -82,8 +95,10 @@ class PyXrefMixin:
|
|
|
82
95
|
|
|
83
96
|
shortname = target.split('.')[-1]
|
|
84
97
|
textnode = innernode('', shortname) # type: ignore[call-arg]
|
|
85
|
-
contnodes = [
|
|
86
|
-
|
|
98
|
+
contnodes = [
|
|
99
|
+
pending_xref_condition('', '', textnode, condition='resolved'),
|
|
100
|
+
pending_xref_condition('', '', *children, condition='*'),
|
|
101
|
+
]
|
|
87
102
|
result.extend(contnodes)
|
|
88
103
|
|
|
89
104
|
return result
|
|
@@ -116,8 +131,18 @@ class PyXrefMixin:
|
|
|
116
131
|
if in_literal or self._delimiters_re.match(sub_target):
|
|
117
132
|
results.append(contnode or innernode(sub_target, sub_target)) # type: ignore[call-arg]
|
|
118
133
|
else:
|
|
119
|
-
results.append(
|
|
120
|
-
|
|
134
|
+
results.append(
|
|
135
|
+
self.make_xref(
|
|
136
|
+
rolename,
|
|
137
|
+
domain,
|
|
138
|
+
sub_target,
|
|
139
|
+
innernode,
|
|
140
|
+
contnode,
|
|
141
|
+
env,
|
|
142
|
+
inliner,
|
|
143
|
+
location,
|
|
144
|
+
)
|
|
145
|
+
)
|
|
121
146
|
|
|
122
147
|
if sub_target in {'Literal', 'typing.Literal', '~typing.Literal'}:
|
|
123
148
|
in_literal = True
|
|
@@ -138,8 +163,7 @@ class PyTypedField(PyXrefMixin, TypedField):
|
|
|
138
163
|
|
|
139
164
|
|
|
140
165
|
class PyObject(ObjectDescription[tuple[str, str]]):
|
|
141
|
-
"""
|
|
142
|
-
Description of a general Python object.
|
|
166
|
+
"""Description of a general Python object.
|
|
143
167
|
|
|
144
168
|
:cvar allow_nesting: Class is an object that allows for nested namespaces
|
|
145
169
|
:vartype allow_nesting: bool
|
|
@@ -161,27 +185,55 @@ class PyObject(ObjectDescription[tuple[str, str]]):
|
|
|
161
185
|
}
|
|
162
186
|
|
|
163
187
|
doc_field_types = [
|
|
164
|
-
PyTypedField(
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
188
|
+
PyTypedField(
|
|
189
|
+
'parameter',
|
|
190
|
+
label=_('Parameters'),
|
|
191
|
+
names=(
|
|
192
|
+
'param',
|
|
193
|
+
'parameter',
|
|
194
|
+
'arg',
|
|
195
|
+
'argument',
|
|
196
|
+
'keyword',
|
|
197
|
+
'kwarg',
|
|
198
|
+
'kwparam',
|
|
199
|
+
),
|
|
200
|
+
typerolename='class',
|
|
201
|
+
typenames=('paramtype', 'type'),
|
|
202
|
+
can_collapse=True,
|
|
203
|
+
),
|
|
204
|
+
PyTypedField(
|
|
205
|
+
'variable',
|
|
206
|
+
label=_('Variables'),
|
|
207
|
+
names=('var', 'ivar', 'cvar'),
|
|
208
|
+
typerolename='class',
|
|
209
|
+
typenames=('vartype',),
|
|
210
|
+
can_collapse=True,
|
|
211
|
+
),
|
|
212
|
+
PyGroupedField(
|
|
213
|
+
'exceptions',
|
|
214
|
+
label=_('Raises'),
|
|
215
|
+
rolename='exc',
|
|
216
|
+
names=('raises', 'raise', 'exception', 'except'),
|
|
217
|
+
can_collapse=True,
|
|
218
|
+
),
|
|
219
|
+
Field(
|
|
220
|
+
'returnvalue',
|
|
221
|
+
label=_('Returns'),
|
|
222
|
+
has_arg=False,
|
|
223
|
+
names=('returns', 'return'),
|
|
224
|
+
),
|
|
225
|
+
PyField(
|
|
226
|
+
'returntype',
|
|
227
|
+
label=_('Return type'),
|
|
228
|
+
has_arg=False,
|
|
229
|
+
names=('rtype',),
|
|
230
|
+
bodyrolename='class',
|
|
231
|
+
),
|
|
180
232
|
]
|
|
181
233
|
|
|
182
234
|
allow_nesting = False
|
|
183
235
|
|
|
184
|
-
def get_signature_prefix(self, sig: str) ->
|
|
236
|
+
def get_signature_prefix(self, sig: str) -> Sequence[nodes.Node]:
|
|
185
237
|
"""May return a prefix to put before the object name in the
|
|
186
238
|
signature.
|
|
187
239
|
"""
|
|
@@ -212,18 +264,17 @@ class PyObject(ObjectDescription[tuple[str, str]]):
|
|
|
212
264
|
classname = self.env.ref_context.get('py:class')
|
|
213
265
|
if classname:
|
|
214
266
|
add_module = False
|
|
215
|
-
if prefix and (prefix == classname or
|
|
216
|
-
prefix.startswith(classname + ".")):
|
|
267
|
+
if prefix and (prefix == classname or prefix.startswith(f'{classname}.')):
|
|
217
268
|
fullname = prefix + name
|
|
218
269
|
# class name is given again in the signature
|
|
219
|
-
prefix = prefix[len(classname):].lstrip('.')
|
|
270
|
+
prefix = prefix[len(classname) :].lstrip('.')
|
|
220
271
|
elif prefix:
|
|
221
272
|
# class name is given in the signature, but different
|
|
222
273
|
# (shouldn't happen)
|
|
223
|
-
fullname = classname
|
|
274
|
+
fullname = f'{classname}.{prefix}{name}'
|
|
224
275
|
else:
|
|
225
276
|
# class name is not given in the signature
|
|
226
|
-
fullname = classname
|
|
277
|
+
fullname = f'{classname}.{name}'
|
|
227
278
|
else:
|
|
228
279
|
add_module = True
|
|
229
280
|
if prefix:
|
|
@@ -237,9 +288,11 @@ class PyObject(ObjectDescription[tuple[str, str]]):
|
|
|
237
288
|
signode['class'] = classname
|
|
238
289
|
signode['fullname'] = fullname
|
|
239
290
|
|
|
240
|
-
max_len = (
|
|
241
|
-
|
|
242
|
-
|
|
291
|
+
max_len = (
|
|
292
|
+
self.config.python_maximum_signature_line_length
|
|
293
|
+
or self.config.maximum_signature_line_length
|
|
294
|
+
or 0
|
|
295
|
+
)
|
|
243
296
|
|
|
244
297
|
# determine if the function arguments (without its type parameters)
|
|
245
298
|
# should be formatted on a multiline or not by removing the width of
|
|
@@ -258,44 +311,72 @@ class PyObject(ObjectDescription[tuple[str, str]]):
|
|
|
258
311
|
and (sig_len - (arglist_span[1] - arglist_span[0])) > max_len > 0
|
|
259
312
|
)
|
|
260
313
|
|
|
314
|
+
trailing_comma = self.env.config.python_trailing_comma_in_multi_line_signatures
|
|
261
315
|
sig_prefix = self.get_signature_prefix(sig)
|
|
262
316
|
if sig_prefix:
|
|
263
317
|
if type(sig_prefix) is str:
|
|
264
|
-
msg = (
|
|
265
|
-
|
|
266
|
-
|
|
318
|
+
msg = (
|
|
319
|
+
'Python directive method get_signature_prefix()'
|
|
320
|
+
' must return a list of nodes.'
|
|
321
|
+
f" Return value was '{sig_prefix}'."
|
|
322
|
+
)
|
|
267
323
|
raise TypeError(msg)
|
|
268
324
|
signode += addnodes.desc_annotation(str(sig_prefix), '', *sig_prefix)
|
|
269
325
|
|
|
270
326
|
if prefix:
|
|
271
327
|
signode += addnodes.desc_addname(prefix, prefix)
|
|
272
|
-
elif modname and add_module and self.
|
|
273
|
-
nodetext = modname
|
|
328
|
+
elif modname and add_module and self.config.add_module_names:
|
|
329
|
+
nodetext = f'{modname}.'
|
|
274
330
|
signode += addnodes.desc_addname(nodetext, nodetext)
|
|
275
331
|
|
|
276
332
|
signode += addnodes.desc_name(name, name)
|
|
277
333
|
|
|
278
334
|
if tp_list:
|
|
279
335
|
try:
|
|
280
|
-
signode += _parse_type_list(
|
|
336
|
+
signode += _parse_type_list(
|
|
337
|
+
tp_list,
|
|
338
|
+
self.env,
|
|
339
|
+
multi_line_type_parameter_list,
|
|
340
|
+
trailing_comma,
|
|
341
|
+
)
|
|
281
342
|
except Exception as exc:
|
|
282
|
-
logger.warning(
|
|
283
|
-
|
|
343
|
+
logger.warning(
|
|
344
|
+
'could not parse tp_list (%r): %s', tp_list, exc, location=signode
|
|
345
|
+
)
|
|
284
346
|
|
|
285
347
|
if arglist:
|
|
286
348
|
try:
|
|
287
|
-
signode += _parse_arglist(
|
|
288
|
-
|
|
349
|
+
signode += _parse_arglist(
|
|
350
|
+
arglist,
|
|
351
|
+
self.env,
|
|
352
|
+
multi_line_parameter_list,
|
|
353
|
+
trailing_comma,
|
|
354
|
+
)
|
|
355
|
+
except SyntaxError as exc:
|
|
289
356
|
# fallback to parse arglist original parser
|
|
290
357
|
# (this may happen if the argument list is incorrectly used
|
|
291
358
|
# as a list of bases when documenting a class)
|
|
292
359
|
# it supports to represent optional arguments (ex. "func(foo [, bar])")
|
|
293
|
-
|
|
360
|
+
logger.debug(
|
|
361
|
+
'syntax error in arglist (%r): %s', arglist, exc, location=signode
|
|
362
|
+
)
|
|
363
|
+
_pseudo_parse_arglist(
|
|
364
|
+
signode,
|
|
365
|
+
arglist,
|
|
366
|
+
multi_line_parameter_list,
|
|
367
|
+
trailing_comma,
|
|
368
|
+
)
|
|
294
369
|
except (NotImplementedError, ValueError) as exc:
|
|
295
370
|
# duplicated parameter names raise ValueError and not a SyntaxError
|
|
296
|
-
logger.warning(
|
|
297
|
-
|
|
298
|
-
|
|
371
|
+
logger.warning(
|
|
372
|
+
'could not parse arglist (%r): %s', arglist, exc, location=signode
|
|
373
|
+
)
|
|
374
|
+
_pseudo_parse_arglist(
|
|
375
|
+
signode,
|
|
376
|
+
arglist,
|
|
377
|
+
multi_line_parameter_list,
|
|
378
|
+
trailing_comma,
|
|
379
|
+
)
|
|
299
380
|
else:
|
|
300
381
|
if self.needs_arglist():
|
|
301
382
|
# for callables, add an empty parameter list
|
|
@@ -307,9 +388,9 @@ class PyObject(ObjectDescription[tuple[str, str]]):
|
|
|
307
388
|
|
|
308
389
|
anno = self.options.get('annotation')
|
|
309
390
|
if anno:
|
|
310
|
-
signode += addnodes.desc_annotation(
|
|
311
|
-
|
|
312
|
-
|
|
391
|
+
signode += addnodes.desc_annotation(
|
|
392
|
+
f' {anno}', '', addnodes.desc_sig_space(), nodes.Text(anno)
|
|
393
|
+
)
|
|
313
394
|
|
|
314
395
|
return fullname, prefix
|
|
315
396
|
|
|
@@ -329,10 +410,11 @@ class PyObject(ObjectDescription[tuple[str, str]]):
|
|
|
329
410
|
msg = 'must be implemented in subclasses'
|
|
330
411
|
raise NotImplementedError(msg)
|
|
331
412
|
|
|
332
|
-
def add_target_and_index(
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
413
|
+
def add_target_and_index(
|
|
414
|
+
self, name_cls: tuple[str, str], sig: str, signode: desc_signature
|
|
415
|
+
) -> None:
|
|
416
|
+
mod_name = self.options.get('module', self.env.ref_context.get('py:module'))
|
|
417
|
+
fullname = (f'{mod_name}.' if mod_name else '') + name_cls[0]
|
|
336
418
|
node_id = make_id(self.env, self.state.document, '', fullname)
|
|
337
419
|
signode['ids'].append(node_id)
|
|
338
420
|
self.state.document.note_explicit_target(signode)
|
|
@@ -342,13 +424,19 @@ class PyObject(ObjectDescription[tuple[str, str]]):
|
|
|
342
424
|
|
|
343
425
|
canonical_name = self.options.get('canonical')
|
|
344
426
|
if canonical_name:
|
|
345
|
-
domain.note_object(
|
|
346
|
-
|
|
427
|
+
domain.note_object(
|
|
428
|
+
canonical_name, self.objtype, node_id, aliased=True, location=signode
|
|
429
|
+
)
|
|
347
430
|
|
|
348
431
|
if 'no-index-entry' not in self.options:
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
432
|
+
if index_text := self.get_index_text(mod_name, name_cls):
|
|
433
|
+
self.indexnode['entries'].append((
|
|
434
|
+
'single',
|
|
435
|
+
index_text,
|
|
436
|
+
node_id,
|
|
437
|
+
'',
|
|
438
|
+
None,
|
|
439
|
+
))
|
|
352
440
|
|
|
353
441
|
def before_content(self) -> None:
|
|
354
442
|
"""Handle object nesting before content
|
|
@@ -398,8 +486,7 @@ class PyObject(ObjectDescription[tuple[str, str]]):
|
|
|
398
486
|
with contextlib.suppress(IndexError):
|
|
399
487
|
classes.pop()
|
|
400
488
|
|
|
401
|
-
self.env.ref_context['py:class'] =
|
|
402
|
-
else None)
|
|
489
|
+
self.env.ref_context['py:class'] = classes[-1] if len(classes) > 0 else None
|
|
403
490
|
if 'module' in self.options:
|
|
404
491
|
modules = self.env.ref_context.setdefault('py:modules', [])
|
|
405
492
|
if modules:
|
|
@@ -411,7 +498,7 @@ class PyObject(ObjectDescription[tuple[str, str]]):
|
|
|
411
498
|
if not sig_node.get('_toc_parts'):
|
|
412
499
|
return ''
|
|
413
500
|
|
|
414
|
-
config = self.
|
|
501
|
+
config = self.config
|
|
415
502
|
objtype = sig_node.parent.get('objtype')
|
|
416
503
|
if config.add_function_parentheses and objtype in {'function', 'method'}:
|
|
417
504
|
parens = '()'
|
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
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
7
|
|
|
8
8
|
from docutils.parsers.rst import directives
|
|
9
9
|
|
|
@@ -17,7 +17,9 @@ from sphinx.util.nodes import make_id, make_refnode
|
|
|
17
17
|
|
|
18
18
|
if TYPE_CHECKING:
|
|
19
19
|
from collections.abc import Iterator, Set
|
|
20
|
+
from typing import Any, ClassVar
|
|
20
21
|
|
|
22
|
+
from docutils import nodes
|
|
21
23
|
from docutils.nodes import Element
|
|
22
24
|
|
|
23
25
|
from sphinx.addnodes import desc_signature, pending_xref
|
|
@@ -32,9 +34,7 @@ dir_sig_re = re.compile(r'\.\. (.+?)::(.*)$')
|
|
|
32
34
|
|
|
33
35
|
|
|
34
36
|
class ReSTMarkup(ObjectDescription[str]):
|
|
35
|
-
"""
|
|
36
|
-
Description of generic reST markup.
|
|
37
|
-
"""
|
|
37
|
+
"""Description of generic reST markup."""
|
|
38
38
|
|
|
39
39
|
option_spec: ClassVar[OptionSpec] = {
|
|
40
40
|
'no-index': directives.flag,
|
|
@@ -46,7 +46,9 @@ class ReSTMarkup(ObjectDescription[str]):
|
|
|
46
46
|
'nocontentsentry': directives.flag,
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
def add_target_and_index(
|
|
49
|
+
def add_target_and_index(
|
|
50
|
+
self, name: str, sig: str, signode: desc_signature
|
|
51
|
+
) -> None:
|
|
50
52
|
node_id = make_id(self.env, self.state.document, self.objtype, name)
|
|
51
53
|
signode['ids'].append(node_id)
|
|
52
54
|
self.state.document.note_explicit_target(signode)
|
|
@@ -55,9 +57,14 @@ class ReSTMarkup(ObjectDescription[str]):
|
|
|
55
57
|
domain.note_object(self.objtype, name, node_id, location=signode)
|
|
56
58
|
|
|
57
59
|
if 'no-index-entry' not in self.options:
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
if index_text := self.get_index_text(self.objtype, name):
|
|
61
|
+
self.indexnode['entries'].append((
|
|
62
|
+
'single',
|
|
63
|
+
index_text,
|
|
64
|
+
node_id,
|
|
65
|
+
'',
|
|
66
|
+
None,
|
|
67
|
+
))
|
|
61
68
|
|
|
62
69
|
def get_index_text(self, objectname: str, name: str) -> str:
|
|
63
70
|
return ''
|
|
@@ -75,12 +82,11 @@ class ReSTMarkup(ObjectDescription[str]):
|
|
|
75
82
|
if not sig_node.get('_toc_parts'):
|
|
76
83
|
return ''
|
|
77
84
|
|
|
78
|
-
config = self.env.app.config
|
|
79
85
|
objtype = sig_node.parent.get('objtype')
|
|
80
86
|
*parents, name = sig_node['_toc_parts']
|
|
81
87
|
if objtype == 'directive:option':
|
|
82
88
|
return f':{name}:'
|
|
83
|
-
if config.toc_object_entries_show_parents in {'domain', 'all'}:
|
|
89
|
+
if self.config.toc_object_entries_show_parents in {'domain', 'all'}:
|
|
84
90
|
name = ':'.join(sig_node['_toc_parts'])
|
|
85
91
|
if objtype == 'role':
|
|
86
92
|
return f':{name}:'
|
|
@@ -98,21 +104,19 @@ def parse_directive(d: str) -> tuple[str, str]:
|
|
|
98
104
|
dir = d.strip()
|
|
99
105
|
if not dir.startswith('.'):
|
|
100
106
|
# Assume it is a directive without syntax
|
|
101
|
-
return
|
|
107
|
+
return dir, ''
|
|
102
108
|
m = dir_sig_re.match(dir)
|
|
103
109
|
if not m:
|
|
104
|
-
return
|
|
110
|
+
return dir, ''
|
|
105
111
|
parsed_dir, parsed_args = m.groups()
|
|
106
112
|
if parsed_args.strip():
|
|
107
|
-
return
|
|
113
|
+
return parsed_dir.strip(), ' ' + parsed_args.strip()
|
|
108
114
|
else:
|
|
109
|
-
return
|
|
115
|
+
return parsed_dir.strip(), ''
|
|
110
116
|
|
|
111
117
|
|
|
112
118
|
class ReSTDirective(ReSTMarkup):
|
|
113
|
-
"""
|
|
114
|
-
Description of a reST directive.
|
|
115
|
-
"""
|
|
119
|
+
"""Description of a reST directive."""
|
|
116
120
|
|
|
117
121
|
def handle_signature(self, sig: str, signode: desc_signature) -> str:
|
|
118
122
|
name, args = parse_directive(sig)
|
|
@@ -138,9 +142,7 @@ class ReSTDirective(ReSTMarkup):
|
|
|
138
142
|
|
|
139
143
|
|
|
140
144
|
class ReSTDirectiveOption(ReSTMarkup):
|
|
141
|
-
"""
|
|
142
|
-
Description of an option for reST directive.
|
|
143
|
-
"""
|
|
145
|
+
"""Description of an option for reST directive."""
|
|
144
146
|
|
|
145
147
|
option_spec: ClassVar[OptionSpec] = ReSTMarkup.option_spec.copy()
|
|
146
148
|
option_spec.update({
|
|
@@ -157,13 +159,16 @@ class ReSTDirectiveOption(ReSTMarkup):
|
|
|
157
159
|
signode['fullname'] = name.strip()
|
|
158
160
|
signode += addnodes.desc_name(desc_name, desc_name)
|
|
159
161
|
if argument:
|
|
160
|
-
|
|
162
|
+
text = f' {argument}'
|
|
163
|
+
signode += addnodes.desc_annotation(text, text)
|
|
161
164
|
if self.options.get('type'):
|
|
162
165
|
text = ' (%s)' % self.options['type']
|
|
163
166
|
signode += addnodes.desc_annotation(text, text)
|
|
164
167
|
return name
|
|
165
168
|
|
|
166
|
-
def add_target_and_index(
|
|
169
|
+
def add_target_and_index(
|
|
170
|
+
self, name: str, sig: str, signode: desc_signature
|
|
171
|
+
) -> None:
|
|
167
172
|
domain = self.env.domains.restructuredtext_domain
|
|
168
173
|
|
|
169
174
|
directive_name = self.current_directive
|
|
@@ -181,9 +186,17 @@ class ReSTDirectiveOption(ReSTMarkup):
|
|
|
181
186
|
|
|
182
187
|
if directive_name:
|
|
183
188
|
key = name[0].upper()
|
|
184
|
-
pair = [
|
|
185
|
-
|
|
186
|
-
|
|
189
|
+
pair = [
|
|
190
|
+
_('%s (directive)') % directive_name,
|
|
191
|
+
_(':%s: (directive option)') % name,
|
|
192
|
+
]
|
|
193
|
+
self.indexnode['entries'].append((
|
|
194
|
+
'pair',
|
|
195
|
+
'; '.join(pair),
|
|
196
|
+
node_id,
|
|
197
|
+
'',
|
|
198
|
+
key,
|
|
199
|
+
))
|
|
187
200
|
else:
|
|
188
201
|
key = name[0].upper()
|
|
189
202
|
text = _(':%s: (directive option)') % name
|
|
@@ -199,9 +212,7 @@ class ReSTDirectiveOption(ReSTMarkup):
|
|
|
199
212
|
|
|
200
213
|
|
|
201
214
|
class ReSTRole(ReSTMarkup):
|
|
202
|
-
"""
|
|
203
|
-
Description of a reST role.
|
|
204
|
-
"""
|
|
215
|
+
"""Description of a reST role."""
|
|
205
216
|
|
|
206
217
|
def handle_signature(self, sig: str, signode: desc_signature) -> str:
|
|
207
218
|
desc_name = f':{sig}:'
|
|
@@ -220,17 +231,17 @@ class ReSTDomain(Domain):
|
|
|
220
231
|
label = 'reStructuredText'
|
|
221
232
|
|
|
222
233
|
object_types = {
|
|
223
|
-
'directive':
|
|
234
|
+
'directive': ObjType(_('directive'), 'dir'),
|
|
224
235
|
'directive:option': ObjType(_('directive-option'), 'dir'),
|
|
225
|
-
'role':
|
|
236
|
+
'role': ObjType(_('role'), 'role'),
|
|
226
237
|
}
|
|
227
238
|
directives = {
|
|
228
239
|
'directive': ReSTDirective,
|
|
229
240
|
'directive:option': ReSTDirectiveOption,
|
|
230
|
-
'role':
|
|
241
|
+
'role': ReSTRole,
|
|
231
242
|
}
|
|
232
243
|
roles = {
|
|
233
|
-
'dir':
|
|
244
|
+
'dir': XRefRole(),
|
|
234
245
|
'role': XRefRole(),
|
|
235
246
|
}
|
|
236
247
|
initial_data: dict[str, dict[tuple[str, str], str]] = {
|
|
@@ -239,13 +250,21 @@ class ReSTDomain(Domain):
|
|
|
239
250
|
|
|
240
251
|
@property
|
|
241
252
|
def objects(self) -> dict[tuple[str, str], tuple[str, str]]:
|
|
242
|
-
|
|
253
|
+
# (objtype, fullname) -> (docname, node_id)
|
|
254
|
+
return self.data.setdefault('objects', {})
|
|
243
255
|
|
|
244
|
-
def note_object(
|
|
256
|
+
def note_object(
|
|
257
|
+
self, objtype: str, name: str, node_id: str, location: Any = None
|
|
258
|
+
) -> None:
|
|
245
259
|
if (objtype, name) in self.objects:
|
|
246
260
|
docname, node_id = self.objects[objtype, name]
|
|
247
|
-
logger.warning(
|
|
248
|
-
|
|
261
|
+
logger.warning(
|
|
262
|
+
__('duplicate description of %s %s, other instance in %s'),
|
|
263
|
+
objtype,
|
|
264
|
+
name,
|
|
265
|
+
docname,
|
|
266
|
+
location=location,
|
|
267
|
+
)
|
|
249
268
|
|
|
250
269
|
self.objects[objtype, name] = (self.env.docname, node_id)
|
|
251
270
|
|
|
@@ -260,9 +279,16 @@ class ReSTDomain(Domain):
|
|
|
260
279
|
if doc in docnames:
|
|
261
280
|
self.objects[typ, name] = (doc, node_id)
|
|
262
281
|
|
|
263
|
-
def resolve_xref(
|
|
264
|
-
|
|
265
|
-
|
|
282
|
+
def resolve_xref(
|
|
283
|
+
self,
|
|
284
|
+
env: BuildEnvironment,
|
|
285
|
+
fromdocname: str,
|
|
286
|
+
builder: Builder,
|
|
287
|
+
typ: str,
|
|
288
|
+
target: str,
|
|
289
|
+
node: pending_xref,
|
|
290
|
+
contnode: Element,
|
|
291
|
+
) -> nodes.reference | None:
|
|
266
292
|
objtypes = self.objtypes_for_role(typ)
|
|
267
293
|
if not objtypes:
|
|
268
294
|
return None
|
|
@@ -270,22 +296,41 @@ class ReSTDomain(Domain):
|
|
|
270
296
|
result = self.objects.get((objtype, target))
|
|
271
297
|
if result:
|
|
272
298
|
todocname, node_id = result
|
|
273
|
-
return make_refnode(
|
|
274
|
-
|
|
299
|
+
return make_refnode(
|
|
300
|
+
builder,
|
|
301
|
+
fromdocname,
|
|
302
|
+
todocname,
|
|
303
|
+
node_id,
|
|
304
|
+
contnode,
|
|
305
|
+
f'{target} {objtype}',
|
|
306
|
+
)
|
|
275
307
|
return None
|
|
276
308
|
|
|
277
|
-
def resolve_any_xref(
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
309
|
+
def resolve_any_xref(
|
|
310
|
+
self,
|
|
311
|
+
env: BuildEnvironment,
|
|
312
|
+
fromdocname: str,
|
|
313
|
+
builder: Builder,
|
|
314
|
+
target: str,
|
|
315
|
+
node: pending_xref,
|
|
316
|
+
contnode: Element,
|
|
317
|
+
) -> list[tuple[str, nodes.reference]]:
|
|
318
|
+
results: list[tuple[str, nodes.reference]] = []
|
|
281
319
|
for objtype in self.object_types:
|
|
282
320
|
result = self.objects.get((objtype, target))
|
|
283
321
|
if result:
|
|
284
322
|
todocname, node_id = result
|
|
285
|
-
results.append(
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
323
|
+
results.append((
|
|
324
|
+
f'rst:{self.role_for_objtype(objtype)}',
|
|
325
|
+
make_refnode(
|
|
326
|
+
builder,
|
|
327
|
+
fromdocname,
|
|
328
|
+
todocname,
|
|
329
|
+
node_id,
|
|
330
|
+
contnode,
|
|
331
|
+
f'{target} {objtype}',
|
|
332
|
+
),
|
|
333
|
+
))
|
|
289
334
|
return results
|
|
290
335
|
|
|
291
336
|
def get_objects(self) -> Iterator[tuple[str, str, str, str, str, int]]:
|