Sphinx 7.1.1__py3-none-any.whl → 7.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 +6 -6
- sphinx/__main__.py +3 -1
- sphinx/addnodes.py +35 -22
- sphinx/application.py +40 -38
- sphinx/builders/__init__.py +16 -12
- sphinx/builders/_epub_base.py +15 -11
- sphinx/builders/changes.py +6 -4
- sphinx/builders/dirhtml.py +4 -2
- sphinx/builders/dummy.py +6 -4
- sphinx/builders/epub3.py +16 -8
- sphinx/builders/gettext.py +40 -43
- sphinx/builders/html/__init__.py +166 -196
- sphinx/builders/html/_assets.py +116 -0
- sphinx/builders/html/transforms.py +4 -2
- sphinx/builders/latex/__init__.py +12 -7
- sphinx/builders/latex/theming.py +5 -2
- sphinx/builders/latex/transforms.py +6 -3
- sphinx/builders/linkcheck.py +21 -13
- sphinx/builders/manpage.py +6 -4
- sphinx/builders/singlehtml.py +16 -9
- sphinx/builders/texinfo.py +11 -6
- sphinx/builders/text.py +8 -3
- sphinx/builders/xml.py +9 -4
- sphinx/cmd/build.py +27 -14
- sphinx/cmd/make_mode.py +13 -4
- sphinx/cmd/quickstart.py +13 -4
- sphinx/config.py +17 -14
- sphinx/deprecation.py +4 -2
- sphinx/directives/__init__.py +44 -12
- sphinx/directives/code.py +5 -4
- sphinx/directives/other.py +92 -44
- sphinx/directives/patches.py +1 -1
- sphinx/domains/__init__.py +11 -8
- sphinx/domains/c.py +67 -57
- sphinx/domains/changeset.py +3 -2
- sphinx/domains/citation.py +2 -1
- sphinx/domains/cpp.py +136 -93
- sphinx/domains/index.py +9 -5
- sphinx/domains/javascript.py +32 -19
- sphinx/domains/math.py +5 -3
- sphinx/domains/python.py +69 -57
- sphinx/domains/rst.py +20 -11
- sphinx/domains/std.py +21 -15
- sphinx/environment/__init__.py +97 -65
- sphinx/environment/adapters/indexentries.py +13 -10
- sphinx/environment/adapters/toctree.py +485 -308
- sphinx/environment/collectors/__init__.py +3 -4
- sphinx/environment/collectors/asset.py +10 -4
- sphinx/environment/collectors/dependencies.py +7 -4
- sphinx/environment/collectors/metadata.py +7 -5
- sphinx/environment/collectors/title.py +5 -3
- sphinx/environment/collectors/toctree.py +13 -8
- sphinx/errors.py +1 -1
- sphinx/events.py +5 -5
- sphinx/ext/apidoc.py +49 -27
- sphinx/ext/autodoc/__init__.py +179 -161
- sphinx/ext/autodoc/directive.py +10 -6
- sphinx/ext/autodoc/importer.py +22 -13
- sphinx/ext/autodoc/mock.py +4 -1
- sphinx/ext/autodoc/preserve_defaults.py +80 -12
- sphinx/ext/autodoc/type_comment.py +14 -10
- sphinx/ext/autodoc/typehints.py +7 -3
- sphinx/ext/autosectionlabel.py +6 -3
- sphinx/ext/autosummary/__init__.py +21 -15
- sphinx/ext/autosummary/generate.py +176 -126
- sphinx/ext/coverage.py +93 -8
- sphinx/ext/doctest.py +28 -17
- sphinx/ext/duration.py +19 -17
- sphinx/ext/extlinks.py +11 -6
- sphinx/ext/githubpages.py +8 -7
- sphinx/ext/graphviz.py +61 -17
- sphinx/ext/ifconfig.py +7 -4
- sphinx/ext/imgconverter.py +4 -2
- sphinx/ext/imgmath.py +29 -23
- sphinx/ext/inheritance_diagram.py +41 -27
- sphinx/ext/intersphinx.py +45 -38
- sphinx/ext/linkcode.py +8 -5
- sphinx/ext/mathjax.py +13 -9
- sphinx/ext/napoleon/__init__.py +3 -3
- sphinx/ext/napoleon/docstring.py +40 -31
- sphinx/ext/todo.py +10 -7
- sphinx/ext/viewcode.py +46 -25
- sphinx/extension.py +1 -1
- sphinx/highlighting.py +20 -12
- sphinx/io.py +5 -4
- sphinx/jinja2glue.py +24 -19
- sphinx/locale/__init__.py +8 -2
- sphinx/locale/ar/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ar/LC_MESSAGES/sphinx.po +756 -740
- sphinx/locale/bg/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/bg/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/bn/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/bn/LC_MESSAGES/sphinx.po +755 -739
- sphinx/locale/ca/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ca/LC_MESSAGES/sphinx.po +768 -752
- sphinx/locale/cak/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cak/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/cs/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cs/LC_MESSAGES/sphinx.po +758 -742
- sphinx/locale/cy/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cy/LC_MESSAGES/sphinx.po +759 -743
- sphinx/locale/da/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/da/LC_MESSAGES/sphinx.po +760 -744
- sphinx/locale/de/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/de/LC_MESSAGES/sphinx.po +759 -743
- sphinx/locale/de_DE/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/de_DE/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/el/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/el/LC_MESSAGES/sphinx.po +763 -747
- sphinx/locale/en_DE/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_DE/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/en_FR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_FR/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/en_GB/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_GB/LC_MESSAGES/sphinx.po +768 -752
- sphinx/locale/en_HK/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_HK/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/eo/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/eo/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/es/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/es/LC_MESSAGES/sphinx.po +767 -751
- sphinx/locale/es_CO/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/es_CO/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/et/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/et/LC_MESSAGES/sphinx.po +762 -746
- sphinx/locale/eu/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/eu/LC_MESSAGES/sphinx.po +755 -739
- sphinx/locale/fa/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fa/LC_MESSAGES/sphinx.po +766 -750
- sphinx/locale/fi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fi/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/fr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fr/LC_MESSAGES/sphinx.po +768 -752
- sphinx/locale/fr_FR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fr_FR/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/gl/LC_MESSAGES/sphinx.js +60 -0
- sphinx/locale/gl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/gl/LC_MESSAGES/sphinx.po +3695 -0
- sphinx/locale/he/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/he/LC_MESSAGES/sphinx.po +755 -739
- sphinx/locale/hi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hi/LC_MESSAGES/sphinx.po +763 -747
- sphinx/locale/hi_IN/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hi_IN/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/hr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hr/LC_MESSAGES/sphinx.po +760 -744
- sphinx/locale/hu/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hu/LC_MESSAGES/sphinx.po +759 -743
- sphinx/locale/id/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/id/LC_MESSAGES/sphinx.po +765 -749
- sphinx/locale/is/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/is/LC_MESSAGES/sphinx.po +760 -744
- sphinx/locale/it/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/it/LC_MESSAGES/sphinx.po +760 -744
- sphinx/locale/ja/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ja/LC_MESSAGES/sphinx.po +767 -751
- sphinx/locale/ka/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ka/LC_MESSAGES/sphinx.po +759 -743
- sphinx/locale/ko/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ko/LC_MESSAGES/sphinx.po +767 -751
- sphinx/locale/lt/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/lt/LC_MESSAGES/sphinx.po +755 -739
- sphinx/locale/lv/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/lv/LC_MESSAGES/sphinx.po +755 -739
- sphinx/locale/mk/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/mk/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/nb_NO/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po +755 -739
- sphinx/locale/ne/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ne/LC_MESSAGES/sphinx.po +755 -739
- sphinx/locale/nl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/nl/LC_MESSAGES/sphinx.po +760 -744
- sphinx/locale/pl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pl/LC_MESSAGES/sphinx.po +762 -745
- sphinx/locale/pt/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po +768 -752
- sphinx/locale/pt_PT/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt_PT/LC_MESSAGES/sphinx.po +755 -739
- sphinx/locale/ro/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ro/LC_MESSAGES/sphinx.po +759 -743
- sphinx/locale/ru/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ru/LC_MESSAGES/sphinx.po +760 -744
- sphinx/locale/si/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/si/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/sk/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sk/LC_MESSAGES/sphinx.po +765 -749
- sphinx/locale/sl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sl/LC_MESSAGES/sphinx.po +755 -739
- sphinx/locale/sphinx.pot +748 -740
- sphinx/locale/sq/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sq/LC_MESSAGES/sphinx.po +768 -752
- sphinx/locale/sr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sr/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/sr@latin/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sr@latin/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/sr_RS/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sr_RS/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/sv/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sv/LC_MESSAGES/sphinx.po +755 -739
- sphinx/locale/ta/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ta/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/te/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/te/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/tr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/tr/LC_MESSAGES/sphinx.po +763 -747
- sphinx/locale/uk_UA/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po +760 -749
- sphinx/locale/ur/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ur/LC_MESSAGES/sphinx.po +759 -748
- sphinx/locale/vi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/vi/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/yue/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/yue/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/zh_CN/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_CN/LC_MESSAGES/sphinx.po +768 -752
- sphinx/locale/zh_HK/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_HK/LC_MESSAGES/sphinx.po +754 -738
- sphinx/locale/zh_TW/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po +767 -751
- sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.po +754 -738
- sphinx/parsers.py +5 -4
- sphinx/project.py +52 -34
- sphinx/pycode/__init__.py +2 -1
- sphinx/pycode/ast.py +7 -13
- sphinx/pycode/parser.py +42 -38
- sphinx/registry.py +35 -29
- sphinx/roles.py +9 -4
- sphinx/search/__init__.py +5 -17
- sphinx/search/da.py +1 -1
- sphinx/search/de.py +1 -1
- sphinx/search/en.py +1 -1
- sphinx/search/es.py +1 -1
- sphinx/search/fi.py +1 -1
- sphinx/search/fr.py +1 -1
- sphinx/search/hu.py +1 -1
- sphinx/search/it.py +1 -1
- sphinx/search/ja.py +1 -1
- sphinx/search/nl.py +1 -1
- sphinx/search/no.py +1 -1
- sphinx/search/pt.py +1 -1
- sphinx/search/ro.py +1 -1
- sphinx/search/ru.py +1 -1
- sphinx/search/sv.py +1 -1
- sphinx/search/tr.py +1 -1
- sphinx/search/zh.py +1 -1
- sphinx/testing/fixtures.py +23 -30
- sphinx/testing/path.py +9 -0
- sphinx/testing/restructuredtext.py +13 -5
- sphinx/testing/util.py +20 -63
- sphinx/texinputs/sphinxlatexobjects.sty +15 -15
- sphinx/themes/agogo/static/agogo.css_t +10 -4
- sphinx/themes/basic/layout.html +1 -1
- sphinx/themes/basic/static/basic.css_t +4 -0
- sphinx/themes/basic/static/documentation_options.js_t +1 -2
- sphinx/themes/basic/static/searchtools.js +17 -9
- sphinx/themes/basic/static/sphinx_highlight.js +13 -3
- sphinx/themes/bizstyle/static/bizstyle.css_t +4 -0
- sphinx/themes/classic/theme.conf +1 -1
- sphinx/themes/epub/static/epub.css_t +6 -1
- sphinx/themes/haiku/theme.conf +1 -1
- sphinx/themes/nature/static/nature.css_t +4 -0
- sphinx/themes/nonav/static/nonav.css_t +6 -1
- sphinx/themes/pyramid/static/pyramid.css_t +4 -0
- sphinx/themes/scrolls/static/scrolls.css_t +4 -0
- sphinx/themes/scrolls/theme.conf +1 -1
- sphinx/themes/sphinxdoc/static/sphinxdoc.css_t +4 -0
- sphinx/theming.py +9 -7
- sphinx/transforms/__init__.py +79 -3
- sphinx/transforms/compact_bullet_list.py +6 -3
- sphinx/transforms/i18n.py +26 -10
- sphinx/transforms/post_transforms/__init__.py +21 -8
- sphinx/transforms/post_transforms/code.py +6 -3
- sphinx/transforms/post_transforms/images.py +13 -9
- sphinx/util/__init__.py +21 -92
- sphinx/util/cfamily.py +7 -4
- sphinx/util/display.py +3 -2
- sphinx/util/docfields.py +7 -6
- sphinx/util/docstrings.py +1 -1
- sphinx/util/docutils.py +41 -31
- sphinx/util/fileutil.py +9 -6
- sphinx/util/i18n.py +21 -18
- sphinx/util/images.py +2 -1
- sphinx/util/index_entries.py +27 -0
- sphinx/util/inspect.py +83 -67
- sphinx/util/inventory.py +4 -2
- sphinx/util/logging.py +9 -6
- sphinx/util/matching.py +5 -2
- sphinx/util/math.py +6 -3
- sphinx/util/nodes.py +70 -31
- sphinx/util/osutil.py +22 -40
- sphinx/util/parallel.py +4 -1
- sphinx/util/rst.py +7 -3
- sphinx/util/tags.py +11 -4
- sphinx/util/template.py +17 -14
- sphinx/util/typing.py +61 -20
- sphinx/versioning.py +6 -4
- sphinx/writers/html.py +1 -1
- sphinx/writers/html5.py +32 -24
- sphinx/writers/latex.py +67 -53
- sphinx/writers/manpage.py +9 -5
- sphinx/writers/texinfo.py +11 -9
- sphinx/writers/text.py +14 -9
- sphinx/writers/xml.py +3 -2
- {sphinx-7.1.1.dist-info → sphinx-7.2.0.dist-info}/METADATA +7 -5
- sphinx-7.2.0.dist-info/RECORD +568 -0
- sphinx/testing/comparer.py +0 -97
- sphinx-7.1.1.dist-info/RECORD +0 -564
- {sphinx-7.1.1.dist-info → sphinx-7.2.0.dist-info}/LICENSE +0 -0
- {sphinx-7.1.1.dist-info → sphinx-7.2.0.dist-info}/WHEEL +0 -0
- {sphinx-7.1.1.dist-info → sphinx-7.2.0.dist-info}/entry_points.txt +0 -0
sphinx/util/typing.py
CHANGED
|
@@ -4,22 +4,26 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import sys
|
|
6
6
|
import typing
|
|
7
|
+
from collections.abc import Sequence
|
|
7
8
|
from struct import Struct
|
|
8
9
|
from types import TracebackType
|
|
9
|
-
from typing import Any, Callable,
|
|
10
|
+
from typing import TYPE_CHECKING, Any, Callable, ForwardRef, TypeVar, Union
|
|
10
11
|
|
|
11
12
|
from docutils import nodes
|
|
12
13
|
from docutils.parsers.rst.states import Inliner
|
|
13
14
|
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
import enum
|
|
17
|
+
|
|
14
18
|
try:
|
|
15
|
-
from types import UnionType # type: ignore
|
|
19
|
+
from types import UnionType # type: ignore[attr-defined] # python 3.10 or above
|
|
16
20
|
except ImportError:
|
|
17
21
|
UnionType = None
|
|
18
22
|
|
|
19
|
-
#
|
|
23
|
+
# classes that have incorrect __module__
|
|
20
24
|
INVALID_BUILTIN_CLASSES = {
|
|
21
|
-
Struct: 'struct.Struct', #
|
|
22
|
-
TracebackType: 'types.TracebackType',
|
|
25
|
+
Struct: 'struct.Struct', # Struct.__module__ == '_struct'
|
|
26
|
+
TracebackType: 'types.TracebackType', # TracebackType.__module__ == 'builtins'
|
|
23
27
|
}
|
|
24
28
|
|
|
25
29
|
|
|
@@ -41,23 +45,23 @@ NoneType = type(None)
|
|
|
41
45
|
PathMatcher = Callable[[str], bool]
|
|
42
46
|
|
|
43
47
|
# common role functions
|
|
44
|
-
RoleFunction = Callable[[str, str, str, int, Inliner,
|
|
45
|
-
|
|
48
|
+
RoleFunction = Callable[[str, str, str, int, Inliner, dict[str, Any], Sequence[str]],
|
|
49
|
+
tuple[list[nodes.Node], list[nodes.system_message]]]
|
|
46
50
|
|
|
47
51
|
# A option spec for directive
|
|
48
|
-
OptionSpec =
|
|
52
|
+
OptionSpec = dict[str, Callable[[str], Any]]
|
|
49
53
|
|
|
50
54
|
# title getter functions for enumerable nodes (see sphinx.domains.std)
|
|
51
55
|
TitleGetter = Callable[[nodes.Node], str]
|
|
52
56
|
|
|
53
57
|
# inventory data on memory
|
|
54
|
-
InventoryItem =
|
|
58
|
+
InventoryItem = tuple[
|
|
55
59
|
str, # project name
|
|
56
60
|
str, # project version
|
|
57
61
|
str, # URL
|
|
58
62
|
str, # display name
|
|
59
63
|
]
|
|
60
|
-
Inventory =
|
|
64
|
+
Inventory = dict[str, dict[str, InventoryItem]]
|
|
61
65
|
|
|
62
66
|
|
|
63
67
|
def get_type_hints(
|
|
@@ -80,8 +84,7 @@ def get_type_hints(
|
|
|
80
84
|
# Failed to evaluate ForwardRef (maybe not runtime checkable)
|
|
81
85
|
return safe_getattr(obj, '__annotations__', {})
|
|
82
86
|
except TypeError:
|
|
83
|
-
# Invalid object is given. But try to get __annotations__ as a fallback
|
|
84
|
-
# the code using type union operator (PEP 604) in python 3.9 or below.
|
|
87
|
+
# Invalid object is given. But try to get __annotations__ as a fallback.
|
|
85
88
|
return safe_getattr(obj, '__annotations__', {})
|
|
86
89
|
except KeyError:
|
|
87
90
|
# a broken class found (refs: https://github.com/sphinx-doc/sphinx/issues/8084)
|
|
@@ -140,6 +143,9 @@ def restify(cls: type | None, mode: str = 'fully-qualified-except-typing') -> st
|
|
|
140
143
|
return ' | '.join(restify(a, mode) for a in cls.__args__)
|
|
141
144
|
elif cls.__module__ in ('__builtin__', 'builtins'):
|
|
142
145
|
if hasattr(cls, '__args__'):
|
|
146
|
+
if not cls.__args__: # Empty tuple, list, ...
|
|
147
|
+
return fr':py:class:`{cls.__name__}`\ [{cls.__args__!r}]'
|
|
148
|
+
|
|
143
149
|
concatenated_args = ', '.join(restify(arg, mode) for arg in cls.__args__)
|
|
144
150
|
return fr':py:class:`{cls.__name__}`\ [{concatenated_args}]'
|
|
145
151
|
else:
|
|
@@ -162,7 +168,7 @@ def restify(cls: type | None, mode: str = 'fully-qualified-except-typing') -> st
|
|
|
162
168
|
return ':py:obj:`~typing.Union`\\ [%s]' % args
|
|
163
169
|
elif inspect.isgenericalias(cls):
|
|
164
170
|
if isinstance(cls.__origin__, typing._SpecialForm): # type: ignore[attr-defined]
|
|
165
|
-
text = restify(cls.__origin__, mode) # type: ignore
|
|
171
|
+
text = restify(cls.__origin__, mode) # type: ignore[attr-defined,arg-type]
|
|
166
172
|
elif getattr(cls, '_name', None):
|
|
167
173
|
cls_name = cls._name # type: ignore[attr-defined]
|
|
168
174
|
if cls.__module__ == 'typing':
|
|
@@ -183,7 +189,14 @@ def restify(cls: type | None, mode: str = 'fully-qualified-except-typing') -> st
|
|
|
183
189
|
args = ', '.join(restify(a, mode) for a in cls.__args__[:-1])
|
|
184
190
|
text += fr"\ [[{args}], {restify(cls.__args__[-1], mode)}]"
|
|
185
191
|
elif cls.__module__ == 'typing' and getattr(origin, '_name', None) == 'Literal':
|
|
186
|
-
|
|
192
|
+
literal_args = []
|
|
193
|
+
for a in cls.__args__:
|
|
194
|
+
if inspect.isenumattribute(a):
|
|
195
|
+
literal_args.append(_format_literal_enum_arg(a, mode=mode))
|
|
196
|
+
else:
|
|
197
|
+
literal_args.append(repr(a))
|
|
198
|
+
text += r"\ [%s]" % ', '.join(literal_args)
|
|
199
|
+
del literal_args
|
|
187
200
|
elif cls.__args__:
|
|
188
201
|
text += r"\ [%s]" % ", ".join(restify(a, mode) for a in cls.__args__)
|
|
189
202
|
|
|
@@ -232,8 +245,9 @@ def stringify_annotation(
|
|
|
232
245
|
from sphinx.util.inspect import isNewType # lazy loading
|
|
233
246
|
|
|
234
247
|
if mode not in {'fully-qualified-except-typing', 'fully-qualified', 'smart'}:
|
|
235
|
-
|
|
236
|
-
|
|
248
|
+
msg = ("'mode' must be one of 'fully-qualified-except-typing', "
|
|
249
|
+
f"'fully-qualified', or 'smart'; got {mode!r}.")
|
|
250
|
+
raise ValueError(msg)
|
|
237
251
|
|
|
238
252
|
if mode == 'smart':
|
|
239
253
|
module_prefix = '~'
|
|
@@ -275,8 +289,12 @@ def stringify_annotation(
|
|
|
275
289
|
elif str(annotation).startswith('typing.Annotated'): # for py310+
|
|
276
290
|
pass
|
|
277
291
|
elif annotation_module == 'builtins' and annotation_qualname:
|
|
278
|
-
if
|
|
279
|
-
|
|
292
|
+
if (args := getattr(annotation, '__args__', None)) is not None: # PEP 585 generic
|
|
293
|
+
if not args: # Empty tuple, list, ...
|
|
294
|
+
return repr(annotation)
|
|
295
|
+
|
|
296
|
+
concatenated_args = ', '.join(stringify_annotation(arg, mode) for arg in args)
|
|
297
|
+
return f'{annotation_qualname}[{concatenated_args}]'
|
|
280
298
|
else:
|
|
281
299
|
return annotation_qualname
|
|
282
300
|
elif annotation is Ellipsis:
|
|
@@ -330,7 +348,21 @@ def stringify_annotation(
|
|
|
330
348
|
returns = stringify_annotation(annotation_args[-1], mode)
|
|
331
349
|
return f'{module_prefix}Callable[[{args}], {returns}]'
|
|
332
350
|
elif qualname == 'Literal':
|
|
333
|
-
|
|
351
|
+
from sphinx.util.inspect import isenumattribute # lazy loading
|
|
352
|
+
|
|
353
|
+
def format_literal_arg(arg):
|
|
354
|
+
if isenumattribute(arg):
|
|
355
|
+
enumcls = arg.__class__
|
|
356
|
+
|
|
357
|
+
if mode == 'smart':
|
|
358
|
+
# MyEnum.member
|
|
359
|
+
return f'{enumcls.__qualname__}.{arg.name}'
|
|
360
|
+
|
|
361
|
+
# module.MyEnum.member
|
|
362
|
+
return f'{enumcls.__module__}.{enumcls.__qualname__}.{arg.name}'
|
|
363
|
+
return repr(arg)
|
|
364
|
+
|
|
365
|
+
args = ', '.join(map(format_literal_arg, annotation_args))
|
|
334
366
|
return f'{module_prefix}Literal[{args}]'
|
|
335
367
|
elif str(annotation).startswith('typing.Annotated'): # for py39+
|
|
336
368
|
return stringify_annotation(annotation_args[0], mode)
|
|
@@ -344,6 +376,14 @@ def stringify_annotation(
|
|
|
344
376
|
return module_prefix + qualname
|
|
345
377
|
|
|
346
378
|
|
|
379
|
+
def _format_literal_enum_arg(arg: enum.Enum, /, *, mode: str) -> str:
|
|
380
|
+
enum_cls = arg.__class__
|
|
381
|
+
if mode == 'smart' or enum_cls.__module__ == 'typing':
|
|
382
|
+
return f':py:attr:`~{enum_cls.__module__}.{enum_cls.__qualname__}.{arg.name}`'
|
|
383
|
+
else:
|
|
384
|
+
return f':py:attr:`{enum_cls.__module__}.{enum_cls.__qualname__}.{arg.name}`'
|
|
385
|
+
|
|
386
|
+
|
|
347
387
|
# deprecated name -> (object to return, canonical path or empty string)
|
|
348
388
|
_DEPRECATED_OBJECTS = {
|
|
349
389
|
'stringify': (stringify_annotation, 'sphinx.util.typing.stringify_annotation'),
|
|
@@ -352,7 +392,8 @@ _DEPRECATED_OBJECTS = {
|
|
|
352
392
|
|
|
353
393
|
def __getattr__(name):
|
|
354
394
|
if name not in _DEPRECATED_OBJECTS:
|
|
355
|
-
|
|
395
|
+
msg = f'module {__name__!r} has no attribute {name!r}'
|
|
396
|
+
raise AttributeError(msg)
|
|
356
397
|
|
|
357
398
|
from sphinx.deprecation import _deprecation_warning
|
|
358
399
|
|
sphinx/versioning.py
CHANGED
|
@@ -5,14 +5,16 @@ import pickle
|
|
|
5
5
|
from itertools import product, zip_longest
|
|
6
6
|
from operator import itemgetter
|
|
7
7
|
from os import path
|
|
8
|
-
from typing import TYPE_CHECKING, Any
|
|
8
|
+
from typing import TYPE_CHECKING, Any
|
|
9
9
|
from uuid import uuid4
|
|
10
10
|
|
|
11
|
-
from docutils.nodes import Node
|
|
12
|
-
|
|
13
11
|
from sphinx.transforms import SphinxTransform
|
|
14
12
|
|
|
15
13
|
if TYPE_CHECKING:
|
|
14
|
+
from collections.abc import Iterator
|
|
15
|
+
|
|
16
|
+
from docutils.nodes import Node
|
|
17
|
+
|
|
16
18
|
from sphinx.application import Sphinx
|
|
17
19
|
|
|
18
20
|
try:
|
|
@@ -89,7 +91,7 @@ def merge_doctrees(old: Node, new: Node, condition: Any) -> Iterator[Node]:
|
|
|
89
91
|
# choose the old node with the best ratio for each new node and set the uid
|
|
90
92
|
# as long as the ratio is under a certain value, in which case we consider
|
|
91
93
|
# them not changed but different
|
|
92
|
-
ratios = sorted(ratios.items(), key=itemgetter(1)) # type: ignore
|
|
94
|
+
ratios = sorted(ratios.items(), key=itemgetter(1)) # type: ignore[assignment]
|
|
93
95
|
for (old_node, new_node), ratio in ratios:
|
|
94
96
|
if new_node in seen:
|
|
95
97
|
continue
|
sphinx/writers/html.py
CHANGED
|
@@ -39,6 +39,6 @@ class HTMLWriter(Writer):
|
|
|
39
39
|
'body_pre_docinfo', 'docinfo', 'body', 'fragment',
|
|
40
40
|
'body_suffix', 'meta', 'title', 'subtitle', 'header',
|
|
41
41
|
'footer', 'html_prolog', 'html_head', 'html_title',
|
|
42
|
-
'html_subtitle', 'html_body'
|
|
42
|
+
'html_subtitle', 'html_body'):
|
|
43
43
|
setattr(self, attr, getattr(visitor, attr, None))
|
|
44
44
|
self.clean_meta = ''.join(self.visitor.meta[2:])
|
sphinx/writers/html5.py
CHANGED
|
@@ -6,20 +6,22 @@ import os
|
|
|
6
6
|
import posixpath
|
|
7
7
|
import re
|
|
8
8
|
import urllib.parse
|
|
9
|
-
from
|
|
9
|
+
from collections.abc import Iterable
|
|
10
|
+
from typing import TYPE_CHECKING, cast
|
|
10
11
|
|
|
11
12
|
from docutils import nodes
|
|
12
|
-
from docutils.nodes import Element, Node, Text
|
|
13
13
|
from docutils.writers.html5_polyglot import HTMLTranslator as BaseTranslator
|
|
14
14
|
|
|
15
15
|
from sphinx import addnodes
|
|
16
|
-
from sphinx.builders import Builder
|
|
17
16
|
from sphinx.locale import _, __, admonitionlabels
|
|
18
17
|
from sphinx.util import logging
|
|
19
18
|
from sphinx.util.docutils import SphinxTranslator
|
|
20
19
|
from sphinx.util.images import get_image_size
|
|
21
20
|
|
|
22
21
|
if TYPE_CHECKING:
|
|
22
|
+
from docutils.nodes import Element, Node, Text
|
|
23
|
+
|
|
24
|
+
from sphinx.builders import Builder
|
|
23
25
|
from sphinx.builders.html import StandaloneHTMLBuilder
|
|
24
26
|
|
|
25
27
|
|
|
@@ -95,7 +97,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator):
|
|
|
95
97
|
def depart_desc_signature(self, node: Element) -> None:
|
|
96
98
|
self.protect_literal_text -= 1
|
|
97
99
|
if not node.get('is_multiline'):
|
|
98
|
-
self.add_permalink_ref(node, _('
|
|
100
|
+
self.add_permalink_ref(node, _('Link to this definition'))
|
|
99
101
|
self.body.append('</dt>\n')
|
|
100
102
|
|
|
101
103
|
def visit_desc_signature_line(self, node: Element) -> None:
|
|
@@ -104,7 +106,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator):
|
|
|
104
106
|
def depart_desc_signature_line(self, node: Element) -> None:
|
|
105
107
|
if node.get('add_permalink'):
|
|
106
108
|
# the permalink info is on the parent desc_signature node
|
|
107
|
-
self.add_permalink_ref(node.parent, _('
|
|
109
|
+
self.add_permalink_ref(node.parent, _('Link to this definition'))
|
|
108
110
|
self.body.append('<br />')
|
|
109
111
|
|
|
110
112
|
def visit_desc_content(self, node: Element) -> None:
|
|
@@ -336,7 +338,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator):
|
|
|
336
338
|
self.depart_reference(node)
|
|
337
339
|
|
|
338
340
|
# overwritten -- we don't want source comments to show up in the HTML
|
|
339
|
-
def visit_comment(self, node: Element) -> None: # type: ignore
|
|
341
|
+
def visit_comment(self, node: Element) -> None: # type: ignore[override]
|
|
340
342
|
raise nodes.SkipNode
|
|
341
343
|
|
|
342
344
|
# overwritten
|
|
@@ -408,10 +410,11 @@ class HTML5Translator(SphinxTranslator, BaseTranslator):
|
|
|
408
410
|
append_fignumber(figtype, node['ids'][0])
|
|
409
411
|
|
|
410
412
|
def add_permalink_ref(self, node: Element, title: str) -> None:
|
|
413
|
+
icon = self.config.html_permalinks_icon
|
|
411
414
|
if node['ids'] and self.config.html_permalinks and self.builder.add_permalinks:
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
+
self.body.append(
|
|
416
|
+
f'<a class="headerlink" href="#{node["ids"][0]}" title="{title}">{icon}</a>',
|
|
417
|
+
)
|
|
415
418
|
|
|
416
419
|
# overwritten
|
|
417
420
|
def visit_bullet_list(self, node: Element) -> None:
|
|
@@ -456,7 +459,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator):
|
|
|
456
459
|
else:
|
|
457
460
|
if isinstance(node.parent.parent.parent, addnodes.glossary):
|
|
458
461
|
# add permalink if glossary terms
|
|
459
|
-
self.add_permalink_ref(node, _('
|
|
462
|
+
self.add_permalink_ref(node, _('Link to this term'))
|
|
460
463
|
|
|
461
464
|
self.body.append('</dt>')
|
|
462
465
|
|
|
@@ -479,16 +482,16 @@ class HTML5Translator(SphinxTranslator, BaseTranslator):
|
|
|
479
482
|
node.parent.hasattr('ids') and node.parent['ids']):
|
|
480
483
|
# add permalink anchor
|
|
481
484
|
if close_tag.startswith('</h'):
|
|
482
|
-
self.add_permalink_ref(node.parent, _('
|
|
485
|
+
self.add_permalink_ref(node.parent, _('Link to this heading'))
|
|
483
486
|
elif close_tag.startswith('</a></h'):
|
|
484
487
|
self.body.append('</a><a class="headerlink" href="#%s" ' %
|
|
485
488
|
node.parent['ids'][0] +
|
|
486
489
|
'title="{}">{}'.format(
|
|
487
|
-
_('
|
|
490
|
+
_('Link to this heading'),
|
|
488
491
|
self.config.html_permalinks_icon))
|
|
489
492
|
elif isinstance(node.parent, nodes.table):
|
|
490
493
|
self.body.append('</span>')
|
|
491
|
-
self.add_permalink_ref(node.parent, _('
|
|
494
|
+
self.add_permalink_ref(node.parent, _('Link to this table'))
|
|
492
495
|
elif isinstance(node.parent, nodes.table):
|
|
493
496
|
self.body.append('</span>')
|
|
494
497
|
|
|
@@ -531,11 +534,11 @@ class HTML5Translator(SphinxTranslator, BaseTranslator):
|
|
|
531
534
|
|
|
532
535
|
# append permalink if available
|
|
533
536
|
if isinstance(node.parent, nodes.container) and node.parent.get('literal_block'):
|
|
534
|
-
self.add_permalink_ref(node.parent, _('
|
|
537
|
+
self.add_permalink_ref(node.parent, _('Link to this code'))
|
|
535
538
|
elif isinstance(node.parent, nodes.figure):
|
|
536
|
-
self.add_permalink_ref(node.parent, _('
|
|
539
|
+
self.add_permalink_ref(node.parent, _('Link to this image'))
|
|
537
540
|
elif node.parent.get('toctree'):
|
|
538
|
-
self.add_permalink_ref(node.parent.parent, _('
|
|
541
|
+
self.add_permalink_ref(node.parent.parent, _('Link to this toctree'))
|
|
539
542
|
|
|
540
543
|
if isinstance(node.parent, nodes.container) and node.parent.get('literal_block'):
|
|
541
544
|
self.body.append('</div>\n')
|
|
@@ -669,7 +672,8 @@ class HTML5Translator(SphinxTranslator, BaseTranslator):
|
|
|
669
672
|
# but it tries the final file name, which does not necessarily exist
|
|
670
673
|
# yet at the time the HTML file is written.
|
|
671
674
|
if not ('width' in node and 'height' in node):
|
|
672
|
-
|
|
675
|
+
path = os.path.join(self.builder.srcdir, olduri) # type: ignore[has-type]
|
|
676
|
+
size = get_image_size(path)
|
|
673
677
|
if size is None:
|
|
674
678
|
logger.warning(
|
|
675
679
|
__('Could not obtain image size. :scale: option is ignored.'),
|
|
@@ -879,7 +883,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator):
|
|
|
879
883
|
else:
|
|
880
884
|
node['classes'].append('row-odd')
|
|
881
885
|
self.body.append(self.starttag(node, 'tr', ''))
|
|
882
|
-
node.column = 0 # type: ignore
|
|
886
|
+
node.column = 0 # type: ignore[attr-defined]
|
|
883
887
|
|
|
884
888
|
def visit_field_list(self, node: Element) -> None:
|
|
885
889
|
self._fieldlist_row_indices.append(0)
|
|
@@ -897,25 +901,29 @@ class HTML5Translator(SphinxTranslator, BaseTranslator):
|
|
|
897
901
|
node['classes'].append('field-odd')
|
|
898
902
|
|
|
899
903
|
def visit_math(self, node: Element, math_env: str = '') -> None:
|
|
900
|
-
|
|
904
|
+
# see validate_math_renderer
|
|
905
|
+
name: str = self.builder.math_renderer_name # type: ignore[assignment]
|
|
901
906
|
visit, _ = self.builder.app.registry.html_inline_math_renderers[name]
|
|
902
907
|
visit(self, node)
|
|
903
908
|
|
|
904
909
|
def depart_math(self, node: Element, math_env: str = '') -> None:
|
|
905
|
-
|
|
910
|
+
# see validate_math_renderer
|
|
911
|
+
name: str = self.builder.math_renderer_name # type: ignore[assignment]
|
|
906
912
|
_, depart = self.builder.app.registry.html_inline_math_renderers[name]
|
|
907
|
-
if depart:
|
|
913
|
+
if depart:
|
|
908
914
|
depart(self, node)
|
|
909
915
|
|
|
910
916
|
def visit_math_block(self, node: Element, math_env: str = '') -> None:
|
|
911
|
-
|
|
917
|
+
# see validate_math_renderer
|
|
918
|
+
name: str = self.builder.math_renderer_name # type: ignore[assignment]
|
|
912
919
|
visit, _ = self.builder.app.registry.html_block_math_renderers[name]
|
|
913
920
|
visit(self, node)
|
|
914
921
|
|
|
915
922
|
def depart_math_block(self, node: Element, math_env: str = '') -> None:
|
|
916
|
-
|
|
923
|
+
# see validate_math_renderer
|
|
924
|
+
name: str = self.builder.math_renderer_name # type: ignore[assignment]
|
|
917
925
|
_, depart = self.builder.app.registry.html_block_math_renderers[name]
|
|
918
|
-
if depart:
|
|
926
|
+
if depart:
|
|
919
927
|
depart(self, node)
|
|
920
928
|
|
|
921
929
|
# See Docutils r9413
|