Sphinx 7.4.7__py3-none-any.whl → 8.0.0rc1__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 +2 -2
- sphinx/_cli/__init__.py +4 -4
- sphinx/application.py +7 -7
- sphinx/builders/__init__.py +2 -3
- sphinx/builders/_epub_base.py +33 -12
- sphinx/builders/changes.py +13 -5
- sphinx/builders/epub3.py +6 -2
- sphinx/builders/html/__init__.py +88 -58
- sphinx/builders/latex/__init__.py +38 -12
- sphinx/builders/latex/transforms.py +1 -1
- sphinx/builders/linkcheck.py +8 -49
- sphinx/builders/texinfo.py +12 -6
- sphinx/builders/text.py +7 -3
- sphinx/builders/xml.py +7 -3
- sphinx/cmd/quickstart.py +10 -20
- sphinx/config.py +12 -12
- sphinx/deprecation.py +8 -8
- sphinx/directives/other.py +2 -3
- sphinx/directives/patches.py +2 -2
- sphinx/domains/__init__.py +4 -2
- sphinx/domains/c/__init__.py +2 -2
- sphinx/domains/c/_ast.py +3 -2
- sphinx/domains/c/_parser.py +4 -3
- sphinx/domains/cpp/__init__.py +2 -2
- sphinx/domains/cpp/_ast.py +1 -2
- sphinx/domains/cpp/_parser.py +2 -2
- sphinx/domains/cpp/_symbol.py +2 -2
- sphinx/domains/math.py +1 -1
- sphinx/domains/python/_object.py +0 -1
- sphinx/domains/std/__init__.py +7 -8
- sphinx/environment/__init__.py +14 -32
- sphinx/environment/adapters/indexentries.py +4 -6
- sphinx/environment/adapters/toctree.py +4 -4
- sphinx/environment/collectors/title.py +1 -1
- sphinx/environment/collectors/toctree.py +1 -1
- sphinx/events.py +3 -1
- sphinx/ext/autodoc/__init__.py +17 -63
- sphinx/ext/autodoc/directive.py +7 -5
- sphinx/ext/autodoc/importer.py +2 -1
- sphinx/ext/autodoc/preserve_defaults.py +2 -2
- sphinx/ext/autosummary/__init__.py +7 -6
- sphinx/ext/autosummary/generate.py +5 -4
- sphinx/ext/doctest.py +5 -5
- sphinx/ext/graphviz.py +1 -1
- sphinx/ext/imgmath.py +1 -1
- sphinx/ext/inheritance_diagram.py +1 -1
- sphinx/ext/intersphinx/__init__.py +25 -5
- sphinx/ext/intersphinx/_cli.py +7 -6
- sphinx/ext/intersphinx/_load.py +240 -115
- sphinx/ext/intersphinx/_resolve.py +12 -11
- sphinx/ext/intersphinx/_shared.py +102 -9
- sphinx/ext/mathjax.py +1 -1
- sphinx/ext/napoleon/docstring.py +2 -2
- sphinx/ext/todo.py +2 -2
- sphinx/ext/viewcode.py +2 -1
- sphinx/highlighting.py +3 -3
- sphinx/io.py +2 -2
- sphinx/jinja2glue.py +13 -6
- sphinx/locale/__init__.py +4 -3
- sphinx/project.py +23 -19
- sphinx/pycode/ast.py +2 -2
- sphinx/pycode/parser.py +2 -2
- sphinx/pygments_styles.py +3 -3
- sphinx/registry.py +3 -8
- sphinx/search/__init__.py +1 -1
- sphinx/testing/path.py +2 -1
- sphinx/testing/util.py +1 -1
- sphinx/texinputs/Makefile.jinja +2 -1
- sphinx/texinputs_win/Makefile.jinja +2 -1
- sphinx/theming.py +3 -12
- sphinx/transforms/__init__.py +5 -5
- sphinx/transforms/references.py +1 -1
- sphinx/util/__init__.py +11 -35
- sphinx/util/_timestamps.py +12 -0
- sphinx/util/cfamily.py +5 -5
- sphinx/util/console.py +4 -3
- sphinx/util/display.py +3 -3
- sphinx/util/docfields.py +1 -1
- sphinx/util/docutils.py +44 -10
- sphinx/util/fileutil.py +25 -20
- sphinx/util/i18n.py +9 -4
- sphinx/util/images.py +3 -2
- sphinx/util/inspect.py +28 -43
- sphinx/util/inventory.py +2 -2
- sphinx/util/matching.py +2 -2
- sphinx/util/math.py +1 -1
- sphinx/util/nodes.py +8 -8
- sphinx/util/osutil.py +29 -28
- sphinx/util/parallel.py +2 -2
- sphinx/util/requests.py +1 -1
- sphinx/util/template.py +3 -3
- sphinx/util/typing.py +36 -72
- sphinx/writers/html.py +1 -1
- sphinx/writers/html5.py +1 -1
- sphinx/writers/latex.py +4 -4
- sphinx/writers/manpage.py +2 -2
- sphinx/writers/texinfo.py +5 -5
- sphinx/writers/text.py +4 -4
- sphinx/writers/xml.py +2 -2
- {sphinx-7.4.7.dist-info → sphinx-8.0.0rc1.dist-info}/METADATA +10 -9
- {sphinx-7.4.7.dist-info → sphinx-8.0.0rc1.dist-info}/RECORD +104 -106
- sphinx/templates/quickstart/Makefile.jinja +0 -98
- sphinx/templates/quickstart/make.bat.jinja +0 -110
- sphinx/util/_pathlib.py +0 -120
- {sphinx-7.4.7.dist-info → sphinx-8.0.0rc1.dist-info}/LICENSE.rst +0 -0
- {sphinx-7.4.7.dist-info → sphinx-8.0.0rc1.dist-info}/WHEEL +0 -0
- {sphinx-7.4.7.dist-info → sphinx-8.0.0rc1.dist-info}/entry_points.txt +0 -0
sphinx/domains/c/_parser.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import TYPE_CHECKING, Any
|
|
3
|
+
from typing import TYPE_CHECKING, Any
|
|
4
4
|
|
|
5
5
|
from sphinx.domains.c._ast import (
|
|
6
6
|
ASTAlignofExpr,
|
|
@@ -53,7 +53,6 @@ from sphinx.domains.c._ast import (
|
|
|
53
53
|
ASTTypeWithInit,
|
|
54
54
|
ASTUnaryOpExpr,
|
|
55
55
|
ASTUnion,
|
|
56
|
-
DeclarationType,
|
|
57
56
|
)
|
|
58
57
|
from sphinx.domains.c._ids import (
|
|
59
58
|
_expression_assignment_ops,
|
|
@@ -80,7 +79,9 @@ from sphinx.util.cfamily import (
|
|
|
80
79
|
)
|
|
81
80
|
|
|
82
81
|
if TYPE_CHECKING:
|
|
83
|
-
from collections.abc import Sequence
|
|
82
|
+
from collections.abc import Callable, Sequence
|
|
83
|
+
|
|
84
|
+
from sphinx.domains.c._ast import DeclarationType
|
|
84
85
|
|
|
85
86
|
|
|
86
87
|
class DefinitionParser(BaseParser):
|
sphinx/domains/cpp/__init__.py
CHANGED
|
@@ -23,7 +23,7 @@ from sphinx.domains.cpp._parser import DefinitionParser
|
|
|
23
23
|
from sphinx.domains.cpp._symbol import Symbol, _DuplicateSymbolError
|
|
24
24
|
from sphinx.errors import NoUri
|
|
25
25
|
from sphinx.locale import _, __
|
|
26
|
-
from sphinx.roles import
|
|
26
|
+
from sphinx.roles import XRefRole
|
|
27
27
|
from sphinx.transforms import SphinxTransform
|
|
28
28
|
from sphinx.transforms.post_transforms import ReferencesResolver
|
|
29
29
|
from sphinx.util import logging
|
|
@@ -33,7 +33,7 @@ from sphinx.util.cfamily import (
|
|
|
33
33
|
anon_identifier_re,
|
|
34
34
|
)
|
|
35
35
|
from sphinx.util.docfields import Field, GroupedField
|
|
36
|
-
from sphinx.util.docutils import SphinxDirective
|
|
36
|
+
from sphinx.util.docutils import SphinxDirective, SphinxRole
|
|
37
37
|
from sphinx.util.nodes import make_refnode
|
|
38
38
|
|
|
39
39
|
if TYPE_CHECKING:
|
sphinx/domains/cpp/_ast.py
CHANGED
|
@@ -24,18 +24,17 @@ from sphinx.util.cfamily import (
|
|
|
24
24
|
ASTBaseBase,
|
|
25
25
|
ASTBaseParenExprList,
|
|
26
26
|
NoOldIdError,
|
|
27
|
-
StringifyTransform,
|
|
28
27
|
UnsupportedMultiCharacterCharLiteral,
|
|
29
28
|
verify_description_mode,
|
|
30
29
|
)
|
|
31
30
|
|
|
32
31
|
if TYPE_CHECKING:
|
|
33
|
-
|
|
34
32
|
from docutils.nodes import Element, TextElement
|
|
35
33
|
|
|
36
34
|
from sphinx.addnodes import desc_signature
|
|
37
35
|
from sphinx.domains.cpp._symbol import Symbol
|
|
38
36
|
from sphinx.environment import BuildEnvironment
|
|
37
|
+
from sphinx.util.cfamily import StringifyTransform
|
|
39
38
|
|
|
40
39
|
|
|
41
40
|
class ASTBase(ASTBaseBase):
|
sphinx/domains/cpp/_parser.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import re
|
|
4
|
-
from typing import TYPE_CHECKING, Any
|
|
4
|
+
from typing import TYPE_CHECKING, Any
|
|
5
5
|
|
|
6
6
|
from sphinx.domains.cpp._ast import (
|
|
7
7
|
ASTAlignofExpr,
|
|
@@ -127,7 +127,7 @@ from sphinx.util.cfamily import (
|
|
|
127
127
|
)
|
|
128
128
|
|
|
129
129
|
if TYPE_CHECKING:
|
|
130
|
-
from collections.abc import Sequence
|
|
130
|
+
from collections.abc import Callable, Sequence
|
|
131
131
|
|
|
132
132
|
logger = logging.getLogger(__name__)
|
|
133
133
|
|
sphinx/domains/cpp/_symbol.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import TYPE_CHECKING, Any,
|
|
3
|
+
from typing import TYPE_CHECKING, Any, NoReturn
|
|
4
4
|
|
|
5
5
|
from sphinx.domains.cpp._ast import (
|
|
6
6
|
ASTDeclaration,
|
|
@@ -17,7 +17,7 @@ from sphinx.locale import __
|
|
|
17
17
|
from sphinx.util import logging
|
|
18
18
|
|
|
19
19
|
if TYPE_CHECKING:
|
|
20
|
-
from collections.abc import Iterator
|
|
20
|
+
from collections.abc import Callable, Iterator
|
|
21
21
|
|
|
22
22
|
from sphinx.environment import BuildEnvironment
|
|
23
23
|
|
sphinx/domains/math.py
CHANGED
|
@@ -74,7 +74,7 @@ class MathDomain(Domain):
|
|
|
74
74
|
def process_doc(self, env: BuildEnvironment, docname: str,
|
|
75
75
|
document: nodes.document) -> None:
|
|
76
76
|
def math_node(node: Node) -> bool:
|
|
77
|
-
return isinstance(node,
|
|
77
|
+
return isinstance(node, nodes.math | nodes.math_block)
|
|
78
78
|
|
|
79
79
|
self.data['has_equations'][docname] = any(document.findall(math_node))
|
|
80
80
|
|
sphinx/domains/python/_object.py
CHANGED
sphinx/domains/std/__init__.py
CHANGED
|
@@ -4,7 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import re
|
|
6
6
|
from copy import copy
|
|
7
|
-
from typing import TYPE_CHECKING, Any,
|
|
7
|
+
from typing import TYPE_CHECKING, Any, ClassVar, Final, cast
|
|
8
8
|
|
|
9
9
|
from docutils import nodes
|
|
10
10
|
from docutils.nodes import Element, Node, system_message
|
|
@@ -23,7 +23,7 @@ from sphinx.util.nodes import clean_astext, make_id, make_refnode
|
|
|
23
23
|
from sphinx.util.parsing import nested_parse_to_nodes
|
|
24
24
|
|
|
25
25
|
if TYPE_CHECKING:
|
|
26
|
-
from collections.abc import Iterable, Iterator
|
|
26
|
+
from collections.abc import Callable, Iterable, Iterator
|
|
27
27
|
|
|
28
28
|
from sphinx.application import Sphinx
|
|
29
29
|
from sphinx.builders import Builder
|
|
@@ -402,7 +402,7 @@ class Glossary(SphinxDirective):
|
|
|
402
402
|
in_comment = False
|
|
403
403
|
was_empty = True
|
|
404
404
|
messages: list[Node] = []
|
|
405
|
-
for line, (source, lineno) in zip(self.content, self.content.items):
|
|
405
|
+
for line, (source, lineno) in zip(self.content, self.content.items, strict=True):
|
|
406
406
|
# empty line -> add to last definition
|
|
407
407
|
if not line:
|
|
408
408
|
if in_definition and entries:
|
|
@@ -814,13 +814,12 @@ class StandardDomain(Domain):
|
|
|
814
814
|
if not sectname:
|
|
815
815
|
continue
|
|
816
816
|
else:
|
|
817
|
-
if (isinstance(node,
|
|
818
|
-
nodes.field_list)) and
|
|
817
|
+
if (isinstance(node, nodes.definition_list | nodes.field_list) and
|
|
819
818
|
node.children):
|
|
820
819
|
node = cast(nodes.Element, node.children[0])
|
|
821
|
-
if isinstance(node,
|
|
820
|
+
if isinstance(node, nodes.field | nodes.definition_list_item):
|
|
822
821
|
node = cast(nodes.Element, node.children[0])
|
|
823
|
-
if isinstance(node,
|
|
822
|
+
if isinstance(node, nodes.term | nodes.field_name):
|
|
824
823
|
sectname = clean_astext(node)
|
|
825
824
|
else:
|
|
826
825
|
toctree = next(node.findall(addnodes.toctree), None)
|
|
@@ -1114,7 +1113,7 @@ class StandardDomain(Domain):
|
|
|
1114
1113
|
return title_getter(elem)
|
|
1115
1114
|
else:
|
|
1116
1115
|
for subnode in elem:
|
|
1117
|
-
if isinstance(subnode,
|
|
1116
|
+
if isinstance(subnode, nodes.caption | nodes.title):
|
|
1118
1117
|
return clean_astext(subnode)
|
|
1119
1118
|
|
|
1120
1119
|
return None
|
sphinx/environment/__init__.py
CHANGED
|
@@ -5,11 +5,10 @@ from __future__ import annotations
|
|
|
5
5
|
import functools
|
|
6
6
|
import os
|
|
7
7
|
import pickle
|
|
8
|
-
import time
|
|
9
8
|
from collections import defaultdict
|
|
10
9
|
from copy import copy
|
|
11
10
|
from os import path
|
|
12
|
-
from typing import TYPE_CHECKING, Any,
|
|
11
|
+
from typing import TYPE_CHECKING, Any, NoReturn
|
|
13
12
|
|
|
14
13
|
from sphinx import addnodes
|
|
15
14
|
from sphinx.environment.adapters import toctree as toctree_adapters
|
|
@@ -17,13 +16,14 @@ from sphinx.errors import BuildEnvironmentError, DocumentError, ExtensionError,
|
|
|
17
16
|
from sphinx.locale import __
|
|
18
17
|
from sphinx.transforms import SphinxTransformer
|
|
19
18
|
from sphinx.util import DownloadFiles, FilenameUniqDict, logging
|
|
19
|
+
from sphinx.util._timestamps import _format_rfc3339_microseconds
|
|
20
20
|
from sphinx.util.docutils import LoggingReporter
|
|
21
21
|
from sphinx.util.i18n import CatalogRepository, docname_to_domain
|
|
22
22
|
from sphinx.util.nodes import is_translatable
|
|
23
|
-
from sphinx.util.osutil import canon_path, os_path
|
|
23
|
+
from sphinx.util.osutil import _last_modified_time, canon_path, os_path
|
|
24
24
|
|
|
25
25
|
if TYPE_CHECKING:
|
|
26
|
-
from collections.abc import Iterator
|
|
26
|
+
from collections.abc import Callable, Iterator
|
|
27
27
|
from pathlib import Path
|
|
28
28
|
|
|
29
29
|
from docutils import nodes
|
|
@@ -59,7 +59,7 @@ default_settings: dict[str, Any] = {
|
|
|
59
59
|
|
|
60
60
|
# This is increased every time an environment attribute is added
|
|
61
61
|
# or changed to properly invalidate pickle files.
|
|
62
|
-
ENV_VERSION =
|
|
62
|
+
ENV_VERSION = 63
|
|
63
63
|
|
|
64
64
|
# config status
|
|
65
65
|
CONFIG_UNSET = -1
|
|
@@ -124,7 +124,7 @@ if TYPE_CHECKING:
|
|
|
124
124
|
def __getitem__(self, key: Literal["todo"]) -> TodoDomain: ... # NoQA: E704
|
|
125
125
|
@overload
|
|
126
126
|
def __getitem__(self, key: str) -> Domain: ... # NoQA: E704
|
|
127
|
-
def __getitem__(self,
|
|
127
|
+
def __getitem__(self, _key: str) -> Domain: raise NotImplementedError # NoQA: E704
|
|
128
128
|
def __setitem__( # NoQA: E301,E704
|
|
129
129
|
self, key: str, value: Domain,
|
|
130
130
|
) -> NoReturn: raise NotImplementedError
|
|
@@ -413,13 +413,13 @@ class BuildEnvironment:
|
|
|
413
413
|
"""
|
|
414
414
|
return self.project.path2doc(filename)
|
|
415
415
|
|
|
416
|
-
def doc2path(self, docname: str, base: bool = True) ->
|
|
416
|
+
def doc2path(self, docname: str, base: bool = True) -> Path:
|
|
417
417
|
"""Return the filename for the document name.
|
|
418
418
|
|
|
419
419
|
If *base* is True, return absolute path under self.srcdir.
|
|
420
420
|
If *base* is False, return relative path to self.srcdir.
|
|
421
421
|
"""
|
|
422
|
-
return self.project.doc2path(docname, base)
|
|
422
|
+
return self.project.doc2path(docname, absolute=base)
|
|
423
423
|
|
|
424
424
|
def relfn2path(self, filename: str, docname: str | None = None) -> tuple[str, str]:
|
|
425
425
|
"""Return paths to a file referenced from a document, relative to
|
|
@@ -508,7 +508,8 @@ class BuildEnvironment:
|
|
|
508
508
|
if newmtime > mtime:
|
|
509
509
|
logger.debug('[build target] outdated %r: %s -> %s',
|
|
510
510
|
docname,
|
|
511
|
-
|
|
511
|
+
_format_rfc3339_microseconds(mtime),
|
|
512
|
+
_format_rfc3339_microseconds(newmtime))
|
|
512
513
|
changed.add(docname)
|
|
513
514
|
continue
|
|
514
515
|
# finally, check the mtime of dependencies
|
|
@@ -528,7 +529,8 @@ class BuildEnvironment:
|
|
|
528
529
|
logger.debug(
|
|
529
530
|
'[build target] outdated %r from dependency %r: %s -> %s',
|
|
530
531
|
docname, deppath,
|
|
531
|
-
|
|
532
|
+
_format_rfc3339_microseconds(mtime),
|
|
533
|
+
_format_rfc3339_microseconds(depmtime),
|
|
532
534
|
)
|
|
533
535
|
changed.add(docname)
|
|
534
536
|
break
|
|
@@ -628,7 +630,7 @@ class BuildEnvironment:
|
|
|
628
630
|
|
|
629
631
|
doctree = pickle.loads(serialised)
|
|
630
632
|
doctree.settings.env = self
|
|
631
|
-
doctree.reporter = LoggingReporter(self.doc2path(docname))
|
|
633
|
+
doctree.reporter = LoggingReporter(str(self.doc2path(docname)))
|
|
632
634
|
return doctree
|
|
633
635
|
|
|
634
636
|
@functools.cached_property
|
|
@@ -650,7 +652,7 @@ class BuildEnvironment:
|
|
|
650
652
|
try:
|
|
651
653
|
doctree = self._write_doc_doctree_cache.pop(docname)
|
|
652
654
|
doctree.settings.env = self
|
|
653
|
-
doctree.reporter = LoggingReporter(self.doc2path(docname))
|
|
655
|
+
doctree.reporter = LoggingReporter(str(self.doc2path(docname)))
|
|
654
656
|
except KeyError:
|
|
655
657
|
doctree = self.get_doctree(docname)
|
|
656
658
|
|
|
@@ -756,26 +758,6 @@ class BuildEnvironment:
|
|
|
756
758
|
self.events.emit('env-check-consistency', self)
|
|
757
759
|
|
|
758
760
|
|
|
759
|
-
def _last_modified_time(filename: str | os.PathLike[str]) -> int:
|
|
760
|
-
"""Return the last modified time of ``filename``.
|
|
761
|
-
|
|
762
|
-
The time is returned as integer microseconds.
|
|
763
|
-
The lowest common denominator of modern file-systems seems to be
|
|
764
|
-
microsecond-level precision.
|
|
765
|
-
|
|
766
|
-
We prefer to err on the side of re-rendering a file,
|
|
767
|
-
so we round up to the nearest microsecond.
|
|
768
|
-
"""
|
|
769
|
-
# upside-down floor division to get the ceiling
|
|
770
|
-
return -(os.stat(filename).st_mtime_ns // -1_000)
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
def _format_modified_time(timestamp: int) -> str:
|
|
774
|
-
"""Return an RFC 3339 formatted string representing the given timestamp."""
|
|
775
|
-
seconds, fraction = divmod(timestamp, 10**6)
|
|
776
|
-
return time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(seconds)) + f'.{fraction // 1_000}'
|
|
777
|
-
|
|
778
|
-
|
|
779
761
|
def _traverse_toctree(
|
|
780
762
|
traversed: set[str],
|
|
781
763
|
parent: str | None,
|
|
@@ -13,16 +13,14 @@ from sphinx.util import logging
|
|
|
13
13
|
from sphinx.util.index_entries import _split_into
|
|
14
14
|
|
|
15
15
|
if TYPE_CHECKING:
|
|
16
|
-
from typing import Literal,
|
|
17
|
-
|
|
18
|
-
from typing_extensions import TypeAlias
|
|
16
|
+
from typing import Literal, TypeAlias
|
|
19
17
|
|
|
20
18
|
from sphinx.builders import Builder
|
|
21
19
|
from sphinx.environment import BuildEnvironment
|
|
22
20
|
|
|
23
|
-
_IndexEntryTarget: TypeAlias = tuple[
|
|
21
|
+
_IndexEntryTarget: TypeAlias = tuple[str | None, str | Literal[False]]
|
|
24
22
|
_IndexEntryTargets: TypeAlias = list[_IndexEntryTarget]
|
|
25
|
-
_IndexEntryCategoryKey: TypeAlias =
|
|
23
|
+
_IndexEntryCategoryKey: TypeAlias = str | None
|
|
26
24
|
_IndexEntrySubItems: TypeAlias = dict[
|
|
27
25
|
str,
|
|
28
26
|
tuple[_IndexEntryTargets, _IndexEntryCategoryKey],
|
|
@@ -32,7 +30,7 @@ if TYPE_CHECKING:
|
|
|
32
30
|
_IndexEntrySubItems,
|
|
33
31
|
_IndexEntryCategoryKey,
|
|
34
32
|
]
|
|
35
|
-
_IndexEntryMap = dict[str, _IndexEntry]
|
|
33
|
+
_IndexEntryMap: TypeAlias = dict[str, _IndexEntry]
|
|
36
34
|
_Index: TypeAlias = list[
|
|
37
35
|
tuple[
|
|
38
36
|
str,
|
|
@@ -319,7 +319,7 @@ def _toctree_entry(
|
|
|
319
319
|
ref, location=toctreenode, type='toc', subtype='no_title')
|
|
320
320
|
except KeyError:
|
|
321
321
|
# this is raised if the included file does not exist
|
|
322
|
-
ref_path = env.doc2path(ref, False)
|
|
322
|
+
ref_path = str(env.doc2path(ref, False))
|
|
323
323
|
if excluded(ref_path):
|
|
324
324
|
message = __('toctree contains reference to excluded document %r')
|
|
325
325
|
elif not included(ref_path):
|
|
@@ -404,7 +404,7 @@ def _toctree_standard_entry(
|
|
|
404
404
|
def _toctree_add_classes(node: Element, depth: int, docname: str) -> None:
|
|
405
405
|
"""Add 'toctree-l%d' and 'current' classes to the toctree."""
|
|
406
406
|
for subnode in node.children:
|
|
407
|
-
if isinstance(subnode,
|
|
407
|
+
if isinstance(subnode, addnodes.compact_paragraph | nodes.list_item):
|
|
408
408
|
# for <p> and <li>, indicate the depth level and recurse
|
|
409
409
|
subnode['classes'].append(f'toctree-l{depth - 1}')
|
|
410
410
|
_toctree_add_classes(subnode, depth, docname)
|
|
@@ -442,7 +442,7 @@ def _toctree_copy(node: ET, depth: int, maxdepth: int, collapse: bool, tags: Tag
|
|
|
442
442
|
|
|
443
443
|
copy = node.copy()
|
|
444
444
|
for subnode in node.children:
|
|
445
|
-
if isinstance(subnode,
|
|
445
|
+
if isinstance(subnode, addnodes.compact_paragraph | nodes.list_item):
|
|
446
446
|
# for <p> and <li>, just recurse
|
|
447
447
|
copy.append(_toctree_copy(subnode, depth, maxdepth, collapse, tags))
|
|
448
448
|
elif isinstance(subnode, nodes.bullet_list):
|
|
@@ -462,7 +462,7 @@ def _toctree_copy(node: ET, depth: int, maxdepth: int, collapse: bool, tags: Tag
|
|
|
462
462
|
copy.append(_toctree_copy(
|
|
463
463
|
child, depth, maxdepth, collapse, tags, # type: ignore[type-var]
|
|
464
464
|
))
|
|
465
|
-
elif isinstance(subnode,
|
|
465
|
+
elif isinstance(subnode, nodes.reference | nodes.title):
|
|
466
466
|
# deep copy references and captions
|
|
467
467
|
sub_node_copy = subnode.copy()
|
|
468
468
|
sub_node_copy.children = [child.deepcopy() for child in subnode.children]
|
|
@@ -43,7 +43,7 @@ class TitleCollector(EnvironmentCollector):
|
|
|
43
43
|
for node in doctree.findall(nodes.section):
|
|
44
44
|
visitor = SphinxContentsFilter(doctree)
|
|
45
45
|
node[0].walkabout(visitor)
|
|
46
|
-
titlenode += visitor.get_entry_text()
|
|
46
|
+
titlenode += visitor.get_entry_text() # type: ignore[no-untyped-call]
|
|
47
47
|
break
|
|
48
48
|
else:
|
|
49
49
|
# document has no title
|
|
@@ -78,7 +78,7 @@ class TocTreeCollector(EnvironmentCollector):
|
|
|
78
78
|
# and unnecessary stuff
|
|
79
79
|
visitor = SphinxContentsFilter(doctree)
|
|
80
80
|
title.walkabout(visitor)
|
|
81
|
-
nodetext = visitor.get_entry_text()
|
|
81
|
+
nodetext = visitor.get_entry_text() # type: ignore[no-untyped-call]
|
|
82
82
|
anchorname = _make_anchor_name(sectionnode['ids'], numentries)
|
|
83
83
|
# make these nodes:
|
|
84
84
|
# list_item -> compact_paragraph -> reference
|
sphinx/events.py
CHANGED
|
@@ -8,7 +8,7 @@ from __future__ import annotations
|
|
|
8
8
|
import contextlib
|
|
9
9
|
from collections import defaultdict
|
|
10
10
|
from operator import attrgetter
|
|
11
|
-
from typing import TYPE_CHECKING, Any,
|
|
11
|
+
from typing import TYPE_CHECKING, Any, NamedTuple
|
|
12
12
|
|
|
13
13
|
from sphinx.errors import ExtensionError, SphinxError
|
|
14
14
|
from sphinx.locale import __
|
|
@@ -16,6 +16,8 @@ from sphinx.util import logging
|
|
|
16
16
|
from sphinx.util.inspect import safe_getattr
|
|
17
17
|
|
|
18
18
|
if TYPE_CHECKING:
|
|
19
|
+
from collections.abc import Callable
|
|
20
|
+
|
|
19
21
|
from sphinx.application import Sphinx
|
|
20
22
|
|
|
21
23
|
|
sphinx/ext/autodoc/__init__.py
CHANGED
|
@@ -10,20 +10,18 @@ from __future__ import annotations
|
|
|
10
10
|
import functools
|
|
11
11
|
import operator
|
|
12
12
|
import re
|
|
13
|
-
import sys
|
|
14
|
-
import warnings
|
|
15
13
|
from inspect import Parameter, Signature
|
|
16
|
-
from typing import TYPE_CHECKING, Any,
|
|
14
|
+
from typing import TYPE_CHECKING, Any, ClassVar, NewType, TypeVar
|
|
17
15
|
|
|
18
16
|
from docutils.statemachine import StringList
|
|
19
17
|
|
|
20
18
|
import sphinx
|
|
21
19
|
from sphinx.config import ENUM, Config
|
|
22
|
-
from sphinx.
|
|
20
|
+
from sphinx.errors import PycodeError
|
|
23
21
|
from sphinx.ext.autodoc.importer import get_class_members, import_module, import_object
|
|
24
22
|
from sphinx.ext.autodoc.mock import ismock, mock, undecorate
|
|
25
23
|
from sphinx.locale import _, __
|
|
26
|
-
from sphinx.pycode import ModuleAnalyzer
|
|
24
|
+
from sphinx.pycode import ModuleAnalyzer
|
|
27
25
|
from sphinx.util import inspect, logging
|
|
28
26
|
from sphinx.util.docstrings import prepare_docstring, separate_metadata
|
|
29
27
|
from sphinx.util.inspect import (
|
|
@@ -42,7 +40,7 @@ from sphinx.util.typing import (
|
|
|
42
40
|
)
|
|
43
41
|
|
|
44
42
|
if TYPE_CHECKING:
|
|
45
|
-
from collections.abc import Iterator, Sequence
|
|
43
|
+
from collections.abc import Callable, Iterator, Sequence
|
|
46
44
|
from types import ModuleType
|
|
47
45
|
|
|
48
46
|
from sphinx.application import Sphinx
|
|
@@ -267,13 +265,6 @@ class ObjectMember:
|
|
|
267
265
|
|
|
268
266
|
This is used for the result of `Documenter.get_module_members()` to
|
|
269
267
|
represent each member of the object.
|
|
270
|
-
|
|
271
|
-
.. Note::
|
|
272
|
-
|
|
273
|
-
An instance of this class behaves as a tuple of (name, object)
|
|
274
|
-
for compatibility to old Sphinx. The behavior will be dropped
|
|
275
|
-
in the future. Therefore extensions should not use the tuple
|
|
276
|
-
interface.
|
|
277
268
|
"""
|
|
278
269
|
|
|
279
270
|
def __init__(self, name: str, obj: Any, *, docstring: str | None = None,
|
|
@@ -284,12 +275,6 @@ class ObjectMember:
|
|
|
284
275
|
self.skipped = skipped
|
|
285
276
|
self.class_ = class_
|
|
286
277
|
|
|
287
|
-
def __getitem__(self, index: int) -> Any:
|
|
288
|
-
warnings.warn('The tuple interface of ObjectMember is deprecated. '
|
|
289
|
-
'Use (obj.__name__, obj.object) instead.',
|
|
290
|
-
RemovedInSphinx80Warning, stacklevel=2)
|
|
291
|
-
return (self.__name__, self.object)[index]
|
|
292
|
-
|
|
293
278
|
|
|
294
279
|
class Documenter:
|
|
295
280
|
"""
|
|
@@ -627,7 +612,7 @@ class Documenter:
|
|
|
627
612
|
|
|
628
613
|
# add additional content (e.g. from document), if present
|
|
629
614
|
if more_content:
|
|
630
|
-
for line, src in zip(more_content.data, more_content.items):
|
|
615
|
+
for line, src in zip(more_content.data, more_content.items, strict=True):
|
|
631
616
|
self.add_line(line, src[0], src[1])
|
|
632
617
|
|
|
633
618
|
def get_object_members(self, want_all: bool) -> tuple[bool, list[ObjectMember]]:
|
|
@@ -684,21 +669,8 @@ class Documenter:
|
|
|
684
669
|
|
|
685
670
|
# process members and determine which to skip
|
|
686
671
|
for obj in members:
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
member = obj.object
|
|
690
|
-
except AttributeError:
|
|
691
|
-
if isinstance(obj, ObjectMember):
|
|
692
|
-
raise
|
|
693
|
-
# To be removed, retained for compatibility.
|
|
694
|
-
# See https://github.com/sphinx-doc/sphinx/issues/11631
|
|
695
|
-
membername, member = obj
|
|
696
|
-
warnings.warn(
|
|
697
|
-
'Returning tuples of (name, object) as '
|
|
698
|
-
'the second return value from get_object_members() is deprecated. '
|
|
699
|
-
'Return ObjectMember(name, object) instances instead.',
|
|
700
|
-
RemovedInSphinx80Warning, stacklevel=2,
|
|
701
|
-
)
|
|
672
|
+
membername = obj.__name__
|
|
673
|
+
member = obj.object
|
|
702
674
|
|
|
703
675
|
# if isattr is True, the member is documented as an attribute
|
|
704
676
|
isattr = member is INSTANCEATTR or (namespace, membername) in attr_docs
|
|
@@ -1003,7 +975,7 @@ class ModuleDocumenter(Documenter):
|
|
|
1003
975
|
super().add_content(None)
|
|
1004
976
|
self.indent = old_indent
|
|
1005
977
|
if more_content:
|
|
1006
|
-
for line, src in zip(more_content.data, more_content.items):
|
|
978
|
+
for line, src in zip(more_content.data, more_content.items, strict=True):
|
|
1007
979
|
self.add_line(line, src[0], src[1])
|
|
1008
980
|
|
|
1009
981
|
@classmethod
|
|
@@ -1410,7 +1382,7 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ
|
|
|
1410
1382
|
if len(sig.parameters) == 0:
|
|
1411
1383
|
return None
|
|
1412
1384
|
|
|
1413
|
-
def dummy(): # NoQA: ANN202
|
|
1385
|
+
def dummy(): # type: ignore[no-untyped-def] # NoQA: ANN202
|
|
1414
1386
|
pass
|
|
1415
1387
|
|
|
1416
1388
|
params = list(sig.parameters.values())
|
|
@@ -1478,7 +1450,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
|
|
1478
1450
|
|
|
1479
1451
|
# Must be higher than FunctionDocumenter, ClassDocumenter, and
|
|
1480
1452
|
# AttributeDocumenter as NewType can be an attribute and is a class
|
|
1481
|
-
# after Python 3.10.
|
|
1453
|
+
# after Python 3.10.
|
|
1482
1454
|
priority = 15
|
|
1483
1455
|
|
|
1484
1456
|
_signature_class: Any = None
|
|
@@ -1504,7 +1476,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
|
|
1504
1476
|
cls: type[Documenter], member: Any, membername: str, isattr: bool, parent: Any,
|
|
1505
1477
|
) -> bool:
|
|
1506
1478
|
return isinstance(member, type) or (
|
|
1507
|
-
isattr and
|
|
1479
|
+
isattr and isinstance(member, NewType | TypeVar))
|
|
1508
1480
|
|
|
1509
1481
|
def import_object(self, raiseerror: bool = False) -> bool:
|
|
1510
1482
|
ret = super().import_object(raiseerror)
|
|
@@ -1515,7 +1487,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
|
|
1515
1487
|
self.doc_as_attr = (self.objpath[-1] != self.object.__name__)
|
|
1516
1488
|
else:
|
|
1517
1489
|
self.doc_as_attr = True
|
|
1518
|
-
if
|
|
1490
|
+
if isinstance(self.object, NewType | TypeVar):
|
|
1519
1491
|
modname = getattr(self.object, '__module__', self.modname)
|
|
1520
1492
|
if modname != self.modname and self.modname.startswith(modname):
|
|
1521
1493
|
bases = self.modname[len(modname):].strip('.').split('.')
|
|
@@ -1524,7 +1496,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
|
|
1524
1496
|
return ret
|
|
1525
1497
|
|
|
1526
1498
|
def _get_signature(self) -> tuple[Any | None, str | None, Signature | None]:
|
|
1527
|
-
if
|
|
1499
|
+
if isinstance(self.object, NewType | TypeVar):
|
|
1528
1500
|
# Suppress signature
|
|
1529
1501
|
return None, None, None
|
|
1530
1502
|
|
|
@@ -1709,14 +1681,14 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
|
|
1709
1681
|
self.directivetype = 'attribute'
|
|
1710
1682
|
super().add_directive_header(sig)
|
|
1711
1683
|
|
|
1712
|
-
if
|
|
1684
|
+
if isinstance(self.object, NewType | TypeVar):
|
|
1713
1685
|
return
|
|
1714
1686
|
|
|
1715
1687
|
if self.analyzer and '.'.join(self.objpath) in self.analyzer.finals:
|
|
1716
1688
|
self.add_line(' :final:', sourcename)
|
|
1717
1689
|
|
|
1718
1690
|
canonical_fullname = self.get_canonical_fullname()
|
|
1719
|
-
if (not self.doc_as_attr and not
|
|
1691
|
+
if (not self.doc_as_attr and not isinstance(self.object, NewType)
|
|
1720
1692
|
and canonical_fullname and self.fullname != canonical_fullname):
|
|
1721
1693
|
self.add_line(' :canonical: %s' % canonical_fullname, sourcename)
|
|
1722
1694
|
|
|
@@ -1768,24 +1740,6 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
|
|
1768
1740
|
if isinstance(self.object, TypeVar):
|
|
1769
1741
|
if self.object.__doc__ == TypeVar.__doc__:
|
|
1770
1742
|
return []
|
|
1771
|
-
if sys.version_info[:2] < (3, 10):
|
|
1772
|
-
if inspect.isNewType(self.object) or isinstance(self.object, TypeVar):
|
|
1773
|
-
parts = self.modname.strip('.').split('.')
|
|
1774
|
-
orig_objpath = self.objpath
|
|
1775
|
-
for i in range(len(parts)):
|
|
1776
|
-
new_modname = '.'.join(parts[:len(parts) - i])
|
|
1777
|
-
new_objpath = parts[len(parts) - i:] + orig_objpath
|
|
1778
|
-
try:
|
|
1779
|
-
analyzer = ModuleAnalyzer.for_module(new_modname)
|
|
1780
|
-
analyzer.analyze()
|
|
1781
|
-
key = ('', new_objpath[-1])
|
|
1782
|
-
comment = list(analyzer.attr_docs.get(key, []))
|
|
1783
|
-
if comment:
|
|
1784
|
-
self.objpath = new_objpath
|
|
1785
|
-
self.modname = new_modname
|
|
1786
|
-
return [comment]
|
|
1787
|
-
except PycodeError:
|
|
1788
|
-
pass
|
|
1789
1743
|
if self.doc_as_attr:
|
|
1790
1744
|
# Don't show the docstring of the class when it is an alias.
|
|
1791
1745
|
if self.get_variable_comment():
|
|
@@ -1849,7 +1803,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
|
|
1849
1803
|
return None
|
|
1850
1804
|
|
|
1851
1805
|
def add_content(self, more_content: StringList | None) -> None:
|
|
1852
|
-
if
|
|
1806
|
+
if isinstance(self.object, NewType):
|
|
1853
1807
|
if self.config.autodoc_typehints_format == "short":
|
|
1854
1808
|
supertype = restify(self.object.__supertype__, "smart")
|
|
1855
1809
|
else:
|
|
@@ -2324,7 +2278,7 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
|
|
|
2324
2278
|
if len(sig.parameters) == 1:
|
|
2325
2279
|
return None
|
|
2326
2280
|
|
|
2327
|
-
def dummy(): # NoQA: ANN202
|
|
2281
|
+
def dummy(): # type: ignore[no-untyped-def] # NoQA: ANN202
|
|
2328
2282
|
pass
|
|
2329
2283
|
|
|
2330
2284
|
params = list(sig.parameters.values())
|
sphinx/ext/autodoc/directive.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from collections.abc import Callable
|
|
4
|
+
from typing import TYPE_CHECKING, Any
|
|
4
5
|
|
|
5
6
|
from docutils import nodes
|
|
6
7
|
from docutils.statemachine import StringList
|
|
@@ -31,14 +32,14 @@ AUTODOC_EXTENDABLE_OPTIONS = ['members', 'private-members', 'special-members',
|
|
|
31
32
|
'exclude-members']
|
|
32
33
|
|
|
33
34
|
|
|
34
|
-
class DummyOptionSpec(dict):
|
|
35
|
+
class DummyOptionSpec(dict[str, Callable[[str], str]]):
|
|
35
36
|
"""An option_spec allows any options."""
|
|
36
37
|
|
|
37
38
|
def __bool__(self) -> bool:
|
|
38
39
|
"""Behaves like some options are defined."""
|
|
39
40
|
return True
|
|
40
41
|
|
|
41
|
-
def __getitem__(self,
|
|
42
|
+
def __getitem__(self, _key: str) -> Callable[[str], str]:
|
|
42
43
|
return lambda x: x
|
|
43
44
|
|
|
44
45
|
|
|
@@ -56,8 +57,9 @@ class DocumenterBridge:
|
|
|
56
57
|
self.state = state
|
|
57
58
|
|
|
58
59
|
|
|
59
|
-
def process_documenter_options(
|
|
60
|
-
|
|
60
|
+
def process_documenter_options(
|
|
61
|
+
documenter: type[Documenter], config: Config, options: dict[str, str],
|
|
62
|
+
) -> Options:
|
|
61
63
|
"""Recognize options of Documenter from user input."""
|
|
62
64
|
default_options = config.autodoc_default_options
|
|
63
65
|
for name in AUTODOC_DEFAULT_OPTIONS:
|
sphinx/ext/autodoc/importer.py
CHANGED
|
@@ -11,8 +11,9 @@ import typing
|
|
|
11
11
|
from enum import Enum
|
|
12
12
|
from typing import TYPE_CHECKING, NamedTuple
|
|
13
13
|
|
|
14
|
+
from sphinx.errors import PycodeError
|
|
14
15
|
from sphinx.ext.autodoc.mock import ismock, undecorate
|
|
15
|
-
from sphinx.pycode import ModuleAnalyzer
|
|
16
|
+
from sphinx.pycode import ModuleAnalyzer
|
|
16
17
|
from sphinx.util import logging
|
|
17
18
|
from sphinx.util.inspect import (
|
|
18
19
|
getannotations,
|
|
@@ -102,9 +102,9 @@ def _is_lambda(x: Any, /) -> bool:
|
|
|
102
102
|
|
|
103
103
|
|
|
104
104
|
def _get_arguments_inner(x: Any, /) -> ast.arguments | None:
|
|
105
|
-
if isinstance(x,
|
|
105
|
+
if isinstance(x, ast.AsyncFunctionDef | ast.FunctionDef | ast.Lambda):
|
|
106
106
|
return x.args
|
|
107
|
-
if isinstance(x,
|
|
107
|
+
if isinstance(x, ast.Assign | ast.AnnAssign):
|
|
108
108
|
return _get_arguments_inner(x.value)
|
|
109
109
|
return None
|
|
110
110
|
|