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
|
@@ -33,17 +33,15 @@ from __future__ import annotations
|
|
|
33
33
|
import builtins
|
|
34
34
|
import hashlib
|
|
35
35
|
import inspect
|
|
36
|
+
import os.path
|
|
36
37
|
import re
|
|
37
|
-
from collections.abc import Iterable, Sequence
|
|
38
38
|
from importlib import import_module
|
|
39
|
-
from
|
|
40
|
-
from typing import TYPE_CHECKING, Any, ClassVar, cast
|
|
39
|
+
from typing import TYPE_CHECKING, cast
|
|
41
40
|
|
|
42
41
|
from docutils import nodes
|
|
43
42
|
from docutils.parsers.rst import directives
|
|
44
43
|
|
|
45
44
|
import sphinx
|
|
46
|
-
from sphinx import addnodes
|
|
47
45
|
from sphinx.ext.graphviz import (
|
|
48
46
|
figure_wrapper,
|
|
49
47
|
graphviz,
|
|
@@ -54,22 +52,30 @@ from sphinx.ext.graphviz import (
|
|
|
54
52
|
from sphinx.util.docutils import SphinxDirective
|
|
55
53
|
|
|
56
54
|
if TYPE_CHECKING:
|
|
55
|
+
from collections.abc import Collection, Iterable, Iterator, Sequence, Set
|
|
56
|
+
from typing import Any, ClassVar, Final
|
|
57
|
+
|
|
57
58
|
from docutils.nodes import Node
|
|
58
59
|
|
|
60
|
+
from sphinx import addnodes
|
|
59
61
|
from sphinx.application import Sphinx
|
|
62
|
+
from sphinx.config import Config
|
|
60
63
|
from sphinx.environment import BuildEnvironment
|
|
61
64
|
from sphinx.util.typing import ExtensionMetadata, OptionSpec
|
|
62
65
|
from sphinx.writers.html5 import HTML5Translator
|
|
63
66
|
from sphinx.writers.latex import LaTeXTranslator
|
|
64
67
|
from sphinx.writers.texinfo import TexinfoTranslator
|
|
65
68
|
|
|
66
|
-
module_sig_re = re.compile(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
+
module_sig_re = re.compile(
|
|
70
|
+
r"""^
|
|
71
|
+
(?:([\w.]*)\.)? # module names
|
|
72
|
+
(\w+) \s* $ # class/final module name
|
|
73
|
+
""",
|
|
74
|
+
re.VERBOSE,
|
|
75
|
+
)
|
|
69
76
|
|
|
70
77
|
|
|
71
|
-
|
|
72
|
-
if inspect.isclass(obj)]
|
|
78
|
+
PY_BUILTINS: Final = frozenset(filter(inspect.isclass, vars(builtins).values()))
|
|
73
79
|
|
|
74
80
|
|
|
75
81
|
def try_import(objname: str) -> Any:
|
|
@@ -101,7 +107,7 @@ def try_import(objname: str) -> Any:
|
|
|
101
107
|
return None
|
|
102
108
|
|
|
103
109
|
|
|
104
|
-
def import_classes(name: str, currmodule: str) -> Any:
|
|
110
|
+
def import_classes(name: str, currmodule: str) -> list[type[Any]]:
|
|
105
111
|
"""Import a class using its fully-qualified *name*."""
|
|
106
112
|
target = None
|
|
107
113
|
|
|
@@ -116,17 +122,21 @@ def import_classes(name: str, currmodule: str) -> Any:
|
|
|
116
122
|
if target is None:
|
|
117
123
|
raise InheritanceException(
|
|
118
124
|
'Could not import class or module %r specified for '
|
|
119
|
-
'inheritance diagram' % name
|
|
125
|
+
'inheritance diagram' % name
|
|
126
|
+
)
|
|
120
127
|
|
|
121
128
|
if inspect.isclass(target):
|
|
122
129
|
# If imported object is a class, just return it
|
|
123
130
|
return [target]
|
|
124
131
|
elif inspect.ismodule(target):
|
|
125
132
|
# If imported object is a module, return classes defined on it
|
|
126
|
-
return [
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
133
|
+
return [
|
|
134
|
+
cls
|
|
135
|
+
for cls in target.__dict__.values()
|
|
136
|
+
if inspect.isclass(cls) and cls.__module__ == target.__name__
|
|
137
|
+
]
|
|
138
|
+
msg = f'{name!r} specified for inheritance diagram is not a class or module'
|
|
139
|
+
raise InheritanceException(msg)
|
|
130
140
|
|
|
131
141
|
|
|
132
142
|
class InheritanceException(Exception):
|
|
@@ -134,39 +144,59 @@ class InheritanceException(Exception):
|
|
|
134
144
|
|
|
135
145
|
|
|
136
146
|
class InheritanceGraph:
|
|
137
|
-
"""
|
|
138
|
-
Given a list of classes, determines the set of classes that they inherit
|
|
147
|
+
"""Given a list of classes, determines the set of classes that they inherit
|
|
139
148
|
from all the way to the root "object", and then is able to generate a
|
|
140
149
|
graphviz dot graph from them.
|
|
141
150
|
"""
|
|
142
151
|
|
|
143
|
-
def __init__(
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
152
|
+
def __init__(
|
|
153
|
+
self,
|
|
154
|
+
class_names: list[str],
|
|
155
|
+
currmodule: str,
|
|
156
|
+
show_builtins: bool = False,
|
|
157
|
+
private_bases: bool = False,
|
|
158
|
+
parts: int = 0,
|
|
159
|
+
aliases: dict[str, str] | None = None,
|
|
160
|
+
top_classes: Set[str] = frozenset(),
|
|
161
|
+
include_subclasses: bool = False,
|
|
162
|
+
) -> None:
|
|
147
163
|
"""*class_names* is a list of child classes to show bases from.
|
|
148
164
|
|
|
149
165
|
If *show_builtins* is True, then Python builtins will be shown
|
|
150
166
|
in the graph.
|
|
151
167
|
"""
|
|
152
168
|
self.class_names = class_names
|
|
153
|
-
classes = self._import_classes(class_names, currmodule)
|
|
154
|
-
|
|
155
|
-
|
|
169
|
+
classes: Collection[type[Any]] = self._import_classes(class_names, currmodule)
|
|
170
|
+
if include_subclasses:
|
|
171
|
+
classes_set = {*classes}
|
|
172
|
+
for cls in tuple(classes_set):
|
|
173
|
+
classes_set.update(_subclasses(cls))
|
|
174
|
+
classes = classes_set
|
|
175
|
+
self.class_info = self._class_info(
|
|
176
|
+
classes, show_builtins, private_bases, parts, aliases, top_classes
|
|
177
|
+
)
|
|
156
178
|
if not self.class_info:
|
|
157
179
|
msg = 'No classes found for inheritance diagram'
|
|
158
180
|
raise InheritanceException(msg)
|
|
159
181
|
|
|
160
|
-
def _import_classes(
|
|
182
|
+
def _import_classes(
|
|
183
|
+
self, class_names: list[str], currmodule: str
|
|
184
|
+
) -> Sequence[type[Any]]:
|
|
161
185
|
"""Import a list of classes."""
|
|
162
|
-
classes: list[Any] = []
|
|
186
|
+
classes: list[type[Any]] = []
|
|
163
187
|
for name in class_names:
|
|
164
188
|
classes.extend(import_classes(name, currmodule))
|
|
165
189
|
return classes
|
|
166
190
|
|
|
167
|
-
def _class_info(
|
|
168
|
-
|
|
169
|
-
|
|
191
|
+
def _class_info(
|
|
192
|
+
self,
|
|
193
|
+
classes: Collection[type[Any]],
|
|
194
|
+
show_builtins: bool,
|
|
195
|
+
private_bases: bool,
|
|
196
|
+
parts: int,
|
|
197
|
+
aliases: dict[str, str] | None,
|
|
198
|
+
top_classes: Set[str],
|
|
199
|
+
) -> list[tuple[str, str, Sequence[str], str | None]]:
|
|
170
200
|
"""Return name and bases for all classes that are ancestors of
|
|
171
201
|
*classes*.
|
|
172
202
|
|
|
@@ -184,8 +214,8 @@ class InheritanceGraph:
|
|
|
184
214
|
"""
|
|
185
215
|
all_classes = {}
|
|
186
216
|
|
|
187
|
-
def recurse(cls: Any) -> None:
|
|
188
|
-
if not show_builtins and cls in
|
|
217
|
+
def recurse(cls: type[Any]) -> None:
|
|
218
|
+
if not show_builtins and cls in PY_BUILTINS:
|
|
189
219
|
return
|
|
190
220
|
if not private_bases and cls.__name__.startswith('_'):
|
|
191
221
|
return
|
|
@@ -197,7 +227,7 @@ class InheritanceGraph:
|
|
|
197
227
|
tooltip = None
|
|
198
228
|
try:
|
|
199
229
|
if cls.__doc__:
|
|
200
|
-
doc = cls.__doc__.strip().split(
|
|
230
|
+
doc = cls.__doc__.strip().split('\n')[0]
|
|
201
231
|
if doc:
|
|
202
232
|
tooltip = '"%s"' % doc.replace('"', '\\"')
|
|
203
233
|
except Exception: # might raise AttributeError for strange classes
|
|
@@ -210,7 +240,7 @@ class InheritanceGraph:
|
|
|
210
240
|
return
|
|
211
241
|
|
|
212
242
|
for base in cls.__bases__:
|
|
213
|
-
if not show_builtins and base in
|
|
243
|
+
if not show_builtins and base in PY_BUILTINS:
|
|
214
244
|
continue
|
|
215
245
|
if not private_bases and base.__name__.startswith('_'):
|
|
216
246
|
continue
|
|
@@ -221,10 +251,13 @@ class InheritanceGraph:
|
|
|
221
251
|
for cls in classes:
|
|
222
252
|
recurse(cls)
|
|
223
253
|
|
|
224
|
-
return
|
|
254
|
+
return [
|
|
255
|
+
(cls_name, fullname, tuple(bases), tooltip)
|
|
256
|
+
for (cls_name, fullname, bases, tooltip) in all_classes.values()
|
|
257
|
+
]
|
|
225
258
|
|
|
226
259
|
def class_name(
|
|
227
|
-
self, cls: Any, parts: int = 0, aliases: dict[str, str] | None = None
|
|
260
|
+
self, cls: type[Any], parts: int = 0, aliases: dict[str, str] | None = None
|
|
228
261
|
) -> str:
|
|
229
262
|
"""Given a class object, return a fully-qualified name.
|
|
230
263
|
|
|
@@ -232,7 +265,7 @@ class InheritanceGraph:
|
|
|
232
265
|
completely general.
|
|
233
266
|
"""
|
|
234
267
|
module = cls.__module__
|
|
235
|
-
if module in
|
|
268
|
+
if module in {'__builtin__', 'builtins'}:
|
|
236
269
|
fullname = cls.__name__
|
|
237
270
|
else:
|
|
238
271
|
fullname = f'{module}.{cls.__qualname__}'
|
|
@@ -250,37 +283,53 @@ class InheritanceGraph:
|
|
|
250
283
|
return [fullname for (_, fullname, _, _) in self.class_info]
|
|
251
284
|
|
|
252
285
|
# These are the default attrs for graphviz
|
|
253
|
-
default_graph_attrs = {
|
|
286
|
+
default_graph_attrs: dict[str, float | int | str] = {
|
|
254
287
|
'rankdir': 'LR',
|
|
255
288
|
'size': '"8.0, 12.0"',
|
|
256
289
|
'bgcolor': 'transparent',
|
|
257
290
|
}
|
|
258
|
-
default_node_attrs = {
|
|
291
|
+
default_node_attrs: dict[str, float | int | str] = {
|
|
259
292
|
'shape': 'box',
|
|
260
293
|
'fontsize': 10,
|
|
261
294
|
'height': 0.25,
|
|
262
|
-
'fontname': '"Vera Sans, DejaVu Sans, Liberation Sans, '
|
|
263
|
-
'Arial, Helvetica, sans"',
|
|
295
|
+
'fontname': '"Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans"',
|
|
264
296
|
'style': '"setlinewidth(0.5),filled"',
|
|
265
297
|
'fillcolor': 'white',
|
|
266
298
|
}
|
|
267
|
-
default_edge_attrs = {
|
|
299
|
+
default_edge_attrs: dict[str, float | int | str] = {
|
|
268
300
|
'arrowsize': 0.5,
|
|
269
301
|
'style': '"setlinewidth(0.5)"',
|
|
270
302
|
}
|
|
271
303
|
|
|
272
|
-
def _format_node_attrs(self, attrs: dict[str,
|
|
304
|
+
def _format_node_attrs(self, attrs: dict[str, float | int | str]) -> str:
|
|
273
305
|
return ','.join(f'{k}={v}' for k, v in sorted(attrs.items()))
|
|
274
306
|
|
|
275
|
-
def _format_graph_attrs(self, attrs: dict[str,
|
|
307
|
+
def _format_graph_attrs(self, attrs: dict[str, float | int | str]) -> str:
|
|
276
308
|
return ''.join(f'{k}={v};\n' for k, v in sorted(attrs.items()))
|
|
277
309
|
|
|
278
|
-
def generate_dot(
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
310
|
+
def generate_dot(
|
|
311
|
+
self,
|
|
312
|
+
name: str,
|
|
313
|
+
urls: dict[str, str] | None = None,
|
|
314
|
+
env: BuildEnvironment | None = None,
|
|
315
|
+
graph_attrs: dict[str, float | int | str] | None = None,
|
|
316
|
+
node_attrs: dict[str, float | int | str] | None = None,
|
|
317
|
+
edge_attrs: dict[str, float | int | str] | None = None,
|
|
318
|
+
) -> str:
|
|
319
|
+
config = env.config if env is not None else None
|
|
320
|
+
return self._generate_dot(
|
|
321
|
+
name, urls, config, graph_attrs, node_attrs, edge_attrs
|
|
322
|
+
)
|
|
323
|
+
|
|
324
|
+
def _generate_dot(
|
|
325
|
+
self,
|
|
326
|
+
name: str,
|
|
327
|
+
urls: dict[str, str] | None = None,
|
|
328
|
+
config: Config | None = None,
|
|
329
|
+
graph_attrs: dict[str, float | int | str] | None = None,
|
|
330
|
+
node_attrs: dict[str, float | int | str] | None = None,
|
|
331
|
+
edge_attrs: dict[str, float | int | str] | None = None,
|
|
332
|
+
) -> str:
|
|
284
333
|
"""Generate a graphviz dot graph from the classes that were passed in
|
|
285
334
|
to __init__.
|
|
286
335
|
|
|
@@ -302,47 +351,45 @@ class InheritanceGraph:
|
|
|
302
351
|
n_attrs.update(node_attrs)
|
|
303
352
|
if edge_attrs is not None:
|
|
304
353
|
e_attrs.update(edge_attrs)
|
|
305
|
-
if
|
|
306
|
-
g_attrs.update(
|
|
307
|
-
n_attrs.update(
|
|
308
|
-
e_attrs.update(
|
|
354
|
+
if config:
|
|
355
|
+
g_attrs.update(config.inheritance_graph_attrs)
|
|
356
|
+
n_attrs.update(config.inheritance_node_attrs)
|
|
357
|
+
e_attrs.update(config.inheritance_edge_attrs)
|
|
309
358
|
|
|
310
359
|
res: list[str] = [
|
|
311
360
|
f'digraph {name} {{\n',
|
|
312
361
|
self._format_graph_attrs(g_attrs),
|
|
313
362
|
]
|
|
314
363
|
|
|
315
|
-
for
|
|
364
|
+
for cls_name, fullname, bases, tooltip in sorted(self.class_info):
|
|
316
365
|
# Write the node
|
|
317
366
|
this_node_attrs = n_attrs.copy()
|
|
318
367
|
if fullname in urls:
|
|
319
|
-
this_node_attrs[
|
|
320
|
-
this_node_attrs[
|
|
368
|
+
this_node_attrs['URL'] = f'"{urls[fullname]}"'
|
|
369
|
+
this_node_attrs['target'] = '"_top"'
|
|
321
370
|
if tooltip:
|
|
322
|
-
this_node_attrs[
|
|
323
|
-
res.append(
|
|
371
|
+
this_node_attrs['tooltip'] = tooltip
|
|
372
|
+
res.append(
|
|
373
|
+
f' "{cls_name}" [{self._format_node_attrs(this_node_attrs)}];\n'
|
|
374
|
+
)
|
|
324
375
|
|
|
325
376
|
# Write the edges
|
|
326
377
|
res.extend(
|
|
327
|
-
' "
|
|
378
|
+
f' "{base_name}" -> "{cls_name}" [{self._format_node_attrs(e_attrs)}];\n'
|
|
328
379
|
for base_name in bases
|
|
329
380
|
)
|
|
330
|
-
res.append(
|
|
331
|
-
return
|
|
381
|
+
res.append('}\n')
|
|
382
|
+
return ''.join(res)
|
|
332
383
|
|
|
333
384
|
|
|
334
385
|
class inheritance_diagram(graphviz):
|
|
335
|
-
"""
|
|
336
|
-
A docutils node to use as a placeholder for the inheritance diagram.
|
|
337
|
-
"""
|
|
386
|
+
"""A docutils node to use as a placeholder for the inheritance diagram."""
|
|
338
387
|
|
|
339
388
|
pass
|
|
340
389
|
|
|
341
390
|
|
|
342
391
|
class InheritanceDiagram(SphinxDirective):
|
|
343
|
-
"""
|
|
344
|
-
Run when the inheritance_diagram directive is first encountered.
|
|
345
|
-
"""
|
|
392
|
+
"""Run when the inheritance_diagram directive is first encountered."""
|
|
346
393
|
|
|
347
394
|
has_content = False
|
|
348
395
|
required_arguments = 1
|
|
@@ -353,6 +400,7 @@ class InheritanceDiagram(SphinxDirective):
|
|
|
353
400
|
'private-bases': directives.flag,
|
|
354
401
|
'caption': directives.unchanged,
|
|
355
402
|
'top-classes': directives.unchanged_required,
|
|
403
|
+
'include-subclasses': directives.flag,
|
|
356
404
|
}
|
|
357
405
|
|
|
358
406
|
def run(self) -> list[Node]:
|
|
@@ -363,20 +411,23 @@ class InheritanceDiagram(SphinxDirective):
|
|
|
363
411
|
# Store the original content for use as a hash
|
|
364
412
|
node['parts'] = self.options.get('parts', 0)
|
|
365
413
|
node['content'] = ', '.join(class_names)
|
|
366
|
-
node['top-classes'] =
|
|
367
|
-
|
|
368
|
-
cls
|
|
369
|
-
if cls
|
|
370
|
-
|
|
414
|
+
node['top-classes'] = frozenset({
|
|
415
|
+
cls_stripped
|
|
416
|
+
for cls in self.options.get('top-classes', '').split(',')
|
|
417
|
+
if (cls_stripped := cls.strip())
|
|
418
|
+
})
|
|
371
419
|
|
|
372
420
|
# Create a graph starting with the list of classes
|
|
373
421
|
try:
|
|
374
422
|
graph = InheritanceGraph(
|
|
375
|
-
class_names,
|
|
423
|
+
class_names,
|
|
424
|
+
self.env.ref_context.get('py:module'), # type: ignore[arg-type]
|
|
376
425
|
parts=node['parts'],
|
|
377
426
|
private_bases='private-bases' in self.options,
|
|
378
427
|
aliases=self.config.inheritance_alias,
|
|
379
|
-
top_classes=node['top-classes']
|
|
428
|
+
top_classes=node['top-classes'],
|
|
429
|
+
include_subclasses='include-subclasses' in self.options,
|
|
430
|
+
)
|
|
380
431
|
except InheritanceException as err:
|
|
381
432
|
return [node.document.reporter.warning(err, line=self.lineno)]
|
|
382
433
|
|
|
@@ -386,7 +437,8 @@ class InheritanceDiagram(SphinxDirective):
|
|
|
386
437
|
# removed from the doctree after we're done with them.
|
|
387
438
|
for name in graph.get_all_class_names():
|
|
388
439
|
refnodes, x = class_role( # type: ignore[misc]
|
|
389
|
-
'class', ':class
|
|
440
|
+
'class', f':class:`{name}`', name, 0, self.state.inliner
|
|
441
|
+
)
|
|
390
442
|
node.extend(refnodes)
|
|
391
443
|
# Store the graph object so we can use it to generate the
|
|
392
444
|
# dot file later
|
|
@@ -401,14 +453,21 @@ class InheritanceDiagram(SphinxDirective):
|
|
|
401
453
|
return [figure]
|
|
402
454
|
|
|
403
455
|
|
|
456
|
+
def _subclasses(cls: type[Any]) -> Iterator[type[Any]]:
|
|
457
|
+
yield cls
|
|
458
|
+
for sub_cls in cls.__subclasses__():
|
|
459
|
+
yield from _subclasses(sub_cls)
|
|
460
|
+
|
|
461
|
+
|
|
404
462
|
def get_graph_hash(node: inheritance_diagram) -> str:
|
|
405
463
|
encoded = (node['content'] + str(node['parts'])).encode()
|
|
406
464
|
return hashlib.md5(encoded, usedforsecurity=False).hexdigest()[-10:]
|
|
407
465
|
|
|
408
466
|
|
|
409
|
-
def html_visit_inheritance_diagram(
|
|
410
|
-
|
|
411
|
-
|
|
467
|
+
def html_visit_inheritance_diagram(
|
|
468
|
+
self: HTML5Translator, node: inheritance_diagram
|
|
469
|
+
) -> None:
|
|
470
|
+
"""Output the graph for HTML. This will insert a PNG with clickable
|
|
412
471
|
image map.
|
|
413
472
|
"""
|
|
414
473
|
graph = node['graph']
|
|
@@ -417,10 +476,12 @@ def html_visit_inheritance_diagram(self: HTML5Translator, node: inheritance_diag
|
|
|
417
476
|
name = 'inheritance%s' % graph_hash
|
|
418
477
|
|
|
419
478
|
# Create a mapping from fully-qualified class names to URLs.
|
|
420
|
-
graphviz_output_format = self.
|
|
421
|
-
current_filename = path.basename(
|
|
479
|
+
graphviz_output_format = self.config.graphviz_output_format.upper()
|
|
480
|
+
current_filename = os.path.basename(
|
|
481
|
+
self.builder.current_docname + self.builder.out_suffix
|
|
482
|
+
)
|
|
422
483
|
urls = {}
|
|
423
|
-
pending_xrefs = cast(Iterable[addnodes.pending_xref], node)
|
|
484
|
+
pending_xrefs = cast('Iterable[addnodes.pending_xref]', node)
|
|
424
485
|
for child in pending_xrefs:
|
|
425
486
|
if child.get('refuri') is not None:
|
|
426
487
|
# Construct the name from the URI if the reference is external via intersphinx
|
|
@@ -436,39 +497,48 @@ def html_visit_inheritance_diagram(self: HTML5Translator, node: inheritance_diag
|
|
|
436
497
|
else:
|
|
437
498
|
urls[child['reftitle']] = '#' + child.get('refid')
|
|
438
499
|
|
|
439
|
-
dotcode = graph.
|
|
440
|
-
render_dot_html(
|
|
441
|
-
|
|
500
|
+
dotcode = graph._generate_dot(name, urls, config=self.config)
|
|
501
|
+
render_dot_html(
|
|
502
|
+
self,
|
|
503
|
+
node,
|
|
504
|
+
dotcode,
|
|
505
|
+
{},
|
|
506
|
+
'inheritance',
|
|
507
|
+
'inheritance',
|
|
508
|
+
alt='Inheritance diagram of ' + node['content'],
|
|
509
|
+
)
|
|
442
510
|
raise nodes.SkipNode
|
|
443
511
|
|
|
444
512
|
|
|
445
|
-
def latex_visit_inheritance_diagram(
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
"""
|
|
513
|
+
def latex_visit_inheritance_diagram(
|
|
514
|
+
self: LaTeXTranslator, node: inheritance_diagram
|
|
515
|
+
) -> None:
|
|
516
|
+
"""Output the graph for LaTeX. This will insert a PDF."""
|
|
449
517
|
graph = node['graph']
|
|
450
518
|
|
|
451
519
|
graph_hash = get_graph_hash(node)
|
|
452
520
|
name = 'inheritance%s' % graph_hash
|
|
453
521
|
|
|
454
|
-
dotcode = graph.
|
|
455
|
-
|
|
522
|
+
dotcode = graph._generate_dot(
|
|
523
|
+
name, config=self.config, graph_attrs={'size': '"6.0,6.0"'}
|
|
524
|
+
)
|
|
456
525
|
render_dot_latex(self, node, dotcode, {}, 'inheritance')
|
|
457
526
|
raise nodes.SkipNode
|
|
458
527
|
|
|
459
528
|
|
|
460
|
-
def texinfo_visit_inheritance_diagram(
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
"""
|
|
529
|
+
def texinfo_visit_inheritance_diagram(
|
|
530
|
+
self: TexinfoTranslator,
|
|
531
|
+
node: inheritance_diagram,
|
|
532
|
+
) -> None:
|
|
533
|
+
"""Output the graph for Texinfo. This will insert a PNG."""
|
|
465
534
|
graph = node['graph']
|
|
466
535
|
|
|
467
536
|
graph_hash = get_graph_hash(node)
|
|
468
537
|
name = 'inheritance%s' % graph_hash
|
|
469
538
|
|
|
470
|
-
dotcode = graph.
|
|
471
|
-
|
|
539
|
+
dotcode = graph._generate_dot(
|
|
540
|
+
name, config=self.config, graph_attrs={'size': '"6.0,6.0"'}
|
|
541
|
+
)
|
|
472
542
|
render_dot_texinfo(self, node, dotcode, {}, 'inheritance')
|
|
473
543
|
raise nodes.SkipNode
|
|
474
544
|
|
|
@@ -485,10 +555,14 @@ def setup(app: Sphinx) -> ExtensionMetadata:
|
|
|
485
555
|
html=(html_visit_inheritance_diagram, None),
|
|
486
556
|
text=(skip, None),
|
|
487
557
|
man=(skip, None),
|
|
488
|
-
texinfo=(texinfo_visit_inheritance_diagram, None)
|
|
558
|
+
texinfo=(texinfo_visit_inheritance_diagram, None),
|
|
559
|
+
)
|
|
489
560
|
app.add_directive('inheritance-diagram', InheritanceDiagram)
|
|
490
|
-
app.add_config_value('inheritance_graph_attrs', {}, '')
|
|
491
|
-
app.add_config_value('inheritance_node_attrs', {}, '')
|
|
492
|
-
app.add_config_value('inheritance_edge_attrs', {}, '')
|
|
493
|
-
app.add_config_value('inheritance_alias', {}, '')
|
|
494
|
-
return {
|
|
561
|
+
app.add_config_value('inheritance_graph_attrs', {}, '', types=frozenset({dict}))
|
|
562
|
+
app.add_config_value('inheritance_node_attrs', {}, '', types=frozenset({dict}))
|
|
563
|
+
app.add_config_value('inheritance_edge_attrs', {}, '', types=frozenset({dict}))
|
|
564
|
+
app.add_config_value('inheritance_alias', {}, '', types=frozenset({dict}))
|
|
565
|
+
return {
|
|
566
|
+
'version': sphinx.__display_version__,
|
|
567
|
+
'parallel_read_safe': True,
|
|
568
|
+
}
|
|
@@ -19,22 +19,23 @@ This works as follows:
|
|
|
19
19
|
from __future__ import annotations
|
|
20
20
|
|
|
21
21
|
__all__ = (
|
|
22
|
+
'IntersphinxDispatcher',
|
|
23
|
+
'IntersphinxRole',
|
|
24
|
+
'IntersphinxRoleResolver',
|
|
22
25
|
'InventoryAdapter',
|
|
23
26
|
'fetch_inventory',
|
|
24
|
-
'
|
|
25
|
-
'validate_intersphinx_mapping',
|
|
26
|
-
'IntersphinxRoleResolver',
|
|
27
|
-
'inventory_exists',
|
|
27
|
+
'inspect_main',
|
|
28
28
|
'install_dispatcher',
|
|
29
|
-
'
|
|
29
|
+
'inventory_exists',
|
|
30
|
+
'load_mappings',
|
|
31
|
+
'missing_reference',
|
|
30
32
|
'resolve_reference_any_inventory',
|
|
31
33
|
'resolve_reference_detect_inventory',
|
|
32
|
-
'
|
|
33
|
-
'
|
|
34
|
-
'IntersphinxRole',
|
|
35
|
-
'inspect_main',
|
|
34
|
+
'resolve_reference_in_inventory',
|
|
35
|
+
'validate_intersphinx_mapping',
|
|
36
36
|
)
|
|
37
37
|
|
|
38
|
+
from types import NoneType
|
|
38
39
|
from typing import TYPE_CHECKING
|
|
39
40
|
|
|
40
41
|
import sphinx
|
|
@@ -63,10 +64,18 @@ if TYPE_CHECKING:
|
|
|
63
64
|
|
|
64
65
|
|
|
65
66
|
def setup(app: Sphinx) -> ExtensionMetadata:
|
|
66
|
-
app.add_config_value('intersphinx_mapping', {}, 'env')
|
|
67
|
-
app.add_config_value('
|
|
68
|
-
app.add_config_value('
|
|
69
|
-
app.add_config_value(
|
|
67
|
+
app.add_config_value('intersphinx_mapping', {}, 'env', types=frozenset({dict}))
|
|
68
|
+
app.add_config_value('intersphinx_resolve_self', '', 'env', types=frozenset({str}))
|
|
69
|
+
app.add_config_value('intersphinx_cache_limit', 5, '', types=frozenset({int}))
|
|
70
|
+
app.add_config_value(
|
|
71
|
+
'intersphinx_timeout', None, '', types=frozenset({float, int, NoneType})
|
|
72
|
+
)
|
|
73
|
+
app.add_config_value(
|
|
74
|
+
'intersphinx_disabled_reftypes',
|
|
75
|
+
['std:doc'],
|
|
76
|
+
'env',
|
|
77
|
+
types=frozenset({frozenset, list, set, tuple}),
|
|
78
|
+
)
|
|
70
79
|
app.connect('config-inited', validate_intersphinx_mapping, priority=800)
|
|
71
80
|
app.connect('builder-inited', load_mappings)
|
|
72
81
|
app.connect('source-read', install_dispatcher)
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"""Command line interface for the intersphinx extension."""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
import logging as _logging
|
|
4
6
|
import sys
|
|
5
7
|
|
|
6
|
-
from sphinx.ext.intersphinx import inspect_main
|
|
8
|
+
from sphinx.ext.intersphinx._cli import inspect_main
|
|
7
9
|
|
|
8
10
|
_logging.basicConfig()
|
|
9
11
|
|
sphinx/ext/intersphinx/_cli.py
CHANGED
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import sys
|
|
6
|
+
from pathlib import Path
|
|
6
7
|
|
|
7
|
-
from sphinx.ext.intersphinx._load import _fetch_inventory
|
|
8
|
+
from sphinx.ext.intersphinx._load import _fetch_inventory, _InvConfig
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
def inspect_main(argv: list[str], /) -> int:
|
|
@@ -17,26 +18,29 @@ def inspect_main(argv: list[str], /) -> int:
|
|
|
17
18
|
)
|
|
18
19
|
return 1
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
filename = argv[0]
|
|
22
|
+
config = _InvConfig(
|
|
23
|
+
intersphinx_cache_limit=5,
|
|
24
|
+
intersphinx_timeout=None,
|
|
25
|
+
tls_verify=False,
|
|
26
|
+
tls_cacerts=None,
|
|
27
|
+
user_agent='',
|
|
28
|
+
)
|
|
25
29
|
|
|
26
30
|
try:
|
|
27
|
-
|
|
28
|
-
inv_data = _fetch_inventory(
|
|
31
|
+
inv = _fetch_inventory(
|
|
29
32
|
target_uri='',
|
|
30
33
|
inv_location=filename,
|
|
31
|
-
config=
|
|
32
|
-
srcdir=
|
|
34
|
+
config=config,
|
|
35
|
+
srcdir=Path(),
|
|
33
36
|
)
|
|
34
|
-
for key in sorted(
|
|
37
|
+
for key in sorted(inv.data):
|
|
35
38
|
print(key)
|
|
36
|
-
inv_entries = sorted(
|
|
37
|
-
for entry,
|
|
39
|
+
inv_entries = sorted(inv.data[key].items())
|
|
40
|
+
for entry, inv_item in inv_entries:
|
|
41
|
+
display_name = inv_item.display_name
|
|
38
42
|
display_name = display_name * (display_name != '-')
|
|
39
|
-
print(f' {entry:<40} {display_name:<40}: {
|
|
43
|
+
print(f' {entry:<40} {display_name:<40}: {inv_item.uri}')
|
|
40
44
|
except ValueError as exc:
|
|
41
45
|
print(exc.args[0] % exc.args[1:], file=sys.stderr)
|
|
42
46
|
return 1
|