diff options
| author | Adam Turner <9087854+aa-turner@users.noreply.github.com> | 2022-12-30 21:13:29 +0000 |
|---|---|---|
| committer | Adam Turner <9087854+aa-turner@users.noreply.github.com> | 2023-01-01 20:48:38 +0000 |
| commit | 26f79b0d2dd88b353ac65623897bdfbe8bc07cab (patch) | |
| tree | 0d2f0c752cf1f49a45cde1d7f414d75a6114f1ce /sphinx/ext | |
| parent | f4c8a0a68e0013808d169357c9f77ebdf19d0f4e (diff) | |
| download | sphinx-git-26f79b0d2dd88b353ac65623897bdfbe8bc07cab.tar.gz | |
Use PEP 595 types
Diffstat (limited to 'sphinx/ext')
28 files changed, 341 insertions, 342 deletions
diff --git a/sphinx/ext/apidoc.py b/sphinx/ext/apidoc.py index 4735e147f..011582d34 100644 --- a/sphinx/ext/apidoc.py +++ b/sphinx/ext/apidoc.py @@ -20,7 +20,7 @@ from copy import copy from fnmatch import fnmatch from importlib.machinery import EXTENSION_SUFFIXES from os import path -from typing import Any, Generator, List, Optional, Tuple +from typing import Any, Generator, Optional import sphinx.locale from sphinx import __display_version__, package_dir @@ -59,7 +59,7 @@ def module_join(*modnames: str) -> str: return '.'.join(filter(None, modnames)) -def is_packagedir(dirname: Optional[str] = None, files: Optional[List[str]] = None) -> bool: +def is_packagedir(dirname: Optional[str] = None, files: Optional[list[str]] = None) -> bool: """Check given *files* contains __init__ file.""" if files is None and dirname is None: return False @@ -106,9 +106,9 @@ def create_module_file(package: str, basename: str, opts: Any, write_file(qualname, text, opts) -def create_package_file(root: str, master_package: str, subroot: str, py_files: List[str], - opts: Any, subs: List[str], is_namespace: bool, - excludes: List[str] = [], user_template_dir: Optional[str] = None +def create_package_file(root: str, master_package: str, subroot: str, py_files: list[str], + opts: Any, subs: list[str], is_namespace: bool, + excludes: list[str] = [], user_template_dir: Optional[str] = None ) -> None: """Build the text of the file and write the file.""" # build a list of sub packages (directories containing an __init__ file) @@ -146,7 +146,7 @@ def create_package_file(root: str, master_package: str, subroot: str, py_files: create_module_file(None, submodule, opts, user_template_dir) -def create_modules_toc_file(modules: List[str], opts: Any, name: str = 'modules', +def create_modules_toc_file(modules: list[str], opts: Any, name: str = 'modules', user_template_dir: Optional[str] = None) -> None: """Create the module's index.""" modules.sort() @@ -167,7 +167,7 @@ def create_modules_toc_file(modules: List[str], opts: Any, name: str = 'modules' write_file(name, text, opts) -def is_skipped_package(dirname: str, opts: Any, excludes: List[str] = []) -> bool: +def is_skipped_package(dirname: str, opts: Any, excludes: list[str] = []) -> bool: """Check if we want to skip this module.""" if not path.isdir(dirname): return False @@ -186,7 +186,7 @@ def is_skipped_package(dirname: str, opts: Any, excludes: List[str] = []) -> boo return False -def is_skipped_module(filename: str, opts: Any, excludes: List[str]) -> bool: +def is_skipped_module(filename: str, opts: Any, excludes: list[str]) -> bool: """Check if we want to skip this module.""" if not path.exists(filename): # skip if the file doesn't exist @@ -198,8 +198,8 @@ def is_skipped_module(filename: str, opts: Any, excludes: List[str]) -> bool: return False -def walk(rootpath: str, excludes: List[str], opts: Any - ) -> Generator[Tuple[str, List[str], List[str]], None, None]: +def walk(rootpath: str, excludes: list[str], opts: Any + ) -> Generator[tuple[str, list[str], list[str]], None, None]: """Walk through the directory and list files and subdirectories up.""" followlinks = getattr(opts, 'followlinks', False) includeprivate = getattr(opts, 'includeprivate', False) @@ -213,7 +213,7 @@ def walk(rootpath: str, excludes: List[str], opts: Any # remove hidden ('.') and private ('_') directories, as well as # excluded dirs if includeprivate: - exclude_prefixes: Tuple[str, ...] = ('.',) + exclude_prefixes: tuple[str, ...] = ('.',) else: exclude_prefixes = ('.', '_') @@ -223,7 +223,7 @@ def walk(rootpath: str, excludes: List[str], opts: Any yield root, subs, files -def has_child_module(rootpath: str, excludes: List[str], opts: Any) -> bool: +def has_child_module(rootpath: str, excludes: list[str], opts: Any) -> bool: """Check the given directory contains child module/s (at least one).""" for _root, _subs, files in walk(rootpath, excludes, opts): if files: @@ -232,8 +232,8 @@ def has_child_module(rootpath: str, excludes: List[str], opts: Any) -> bool: return False -def recurse_tree(rootpath: str, excludes: List[str], opts: Any, - user_template_dir: Optional[str] = None) -> List[str]: +def recurse_tree(rootpath: str, excludes: list[str], opts: Any, + user_template_dir: Optional[str] = None) -> list[str]: """ Look for every file in the directory tree and create the corresponding ReST files. @@ -286,7 +286,7 @@ def recurse_tree(rootpath: str, excludes: List[str], opts: Any, return toplevels -def is_excluded(root: str, excludes: List[str]) -> bool: +def is_excluded(root: str, excludes: list[str]) -> bool: """Check if the directory is in the exclude list. Note: by having trailing slashes, we avoid common prefix issues, like @@ -395,7 +395,7 @@ Note: By default this script will not overwrite already created files.""")) return parser -def main(argv: List[str] = sys.argv[1:]) -> int: +def main(argv: list[str] = sys.argv[1:]) -> int: """Parse and check the command line arguments.""" sphinx.locale.setlocale(locale.LC_ALL, '') sphinx.locale.init_console(os.path.join(package_dir, 'locale'), 'sphinx') diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py index 87983482d..b0419b172 100644 --- a/sphinx/ext/autodoc/__init__.py +++ b/sphinx/ext/autodoc/__init__.py @@ -10,8 +10,8 @@ from __future__ import annotations import re from inspect import Parameter, Signature from types import ModuleType -from typing import (TYPE_CHECKING, Any, Callable, Dict, Iterator, List, Optional, Sequence, - Set, Tuple, Type, TypeVar, Union) +from typing import (TYPE_CHECKING, Any, Callable, Iterator, List, Optional, Sequence, Tuple, + TypeVar, Union) from docutils.statemachine import StringList @@ -81,7 +81,7 @@ INSTANCEATTR = object() SLOTSATTR = object() -def members_option(arg: Any) -> Union[object, List[str]]: +def members_option(arg: Any) -> Union[object, list[str]]: """Used to convert the :members: option to auto directives.""" if arg in (None, True): return ALL @@ -91,14 +91,14 @@ def members_option(arg: Any) -> Union[object, List[str]]: return [x.strip() for x in arg.split(',') if x.strip()] -def exclude_members_option(arg: Any) -> Union[object, Set[str]]: +def exclude_members_option(arg: Any) -> Union[object, set[str]]: """Used to convert the :exclude-members: option.""" if arg in (None, True): return EMPTY return {x.strip() for x in arg.split(',') if x.strip()} -def inherited_members_option(arg: Any) -> Set[str]: +def inherited_members_option(arg: Any) -> set[str]: """Used to convert the :inherited-members: option to auto directives.""" if arg in (None, True): return {'object'} @@ -144,7 +144,7 @@ def bool_option(arg: Any) -> bool: return True -def merge_members_option(options: Dict) -> None: +def merge_members_option(options: dict) -> None: """Merge :private-members: and :special-members: options to the :members: option. """ @@ -174,7 +174,7 @@ def cut_lines(pre: int, post: int = 0, what: Optional[str] = None) -> Callable: This can (and should) be used in place of :confval:`automodule_skip_lines`. """ - def process(app: Sphinx, what_: str, name: str, obj: Any, options: Any, lines: List[str] + def process(app: Sphinx, what_: str, name: str, obj: Any, options: Any, lines: list[str] ) -> None: if what and what_ not in what: return @@ -206,7 +206,7 @@ def between( """ marker_re = re.compile(marker) - def process(app: Sphinx, what_: str, name: str, obj: Any, options: Any, lines: List[str] + def process(app: Sphinx, what_: str, name: str, obj: Any, options: Any, lines: list[str] ) -> None: if what and what_ not in what: return @@ -325,7 +325,7 @@ class Documenter: # qualified name (all set after resolve_name succeeds) self.modname: str = None self.module: ModuleType = None - self.objpath: List[str] = None + self.objpath: list[str] = None self.fullname: str = None # extra signature items (arguments and return annotation, # also set after resolve_name succeeds) @@ -340,7 +340,7 @@ class Documenter: self.analyzer: ModuleAnalyzer = None @property - def documenters(self) -> Dict[str, Type["Documenter"]]: + def documenters(self) -> dict[str, type["Documenter"]]: """Returns registered Documenter classes""" return self.env.app.registry.documenters @@ -352,7 +352,7 @@ class Documenter: self.directive.result.append('', source, *lineno) def resolve_name(self, modname: str, parents: Any, path: str, base: Any - ) -> Tuple[str, List[str]]: + ) -> tuple[str, list[str]]: """Resolve the module and name of the object to document given by the arguments and the current module/class. @@ -529,7 +529,7 @@ class Documenter: # etc. don't support a prepended module name self.add_line(' :module: %s' % self.modname, sourcename) - def get_doc(self) -> Optional[List[List[str]]]: + def get_doc(self) -> Optional[list[list[str]]]: """Decode and return lines of the docstring(s) for the object. When it returns None, autodoc-process-docstring will not be called for this @@ -542,7 +542,7 @@ class Documenter: return [prepare_docstring(docstring, tab_width)] return [] - def process_doc(self, docstrings: List[List[str]]) -> Iterator[str]: + def process_doc(self, docstrings: list[list[str]]) -> Iterator[str]: """Let the user process the docstrings before adding them.""" for docstringlines in docstrings: if self.env.app: @@ -610,7 +610,7 @@ class Documenter: for line, src in zip(more_content.data, more_content.items): self.add_line(line, src[0], src[1]) - def get_object_members(self, want_all: bool) -> Tuple[bool, ObjectMembers]: + def get_object_members(self, want_all: bool) -> tuple[bool, ObjectMembers]: """Return `(members_check_module, members)` where `members` is a list of `(membername, member)` pairs of the members of *self.object*. @@ -620,7 +620,7 @@ class Documenter: raise NotImplementedError('must be implemented in subclasses') def filter_members(self, members: ObjectMembers, want_all: bool - ) -> List[Tuple[str, Any, bool]]: + ) -> list[tuple[str, Any, bool]]: """Filter the given member list. Members are skipped if @@ -792,7 +792,7 @@ class Documenter: members_check_module, members = self.get_object_members(want_all) # document non-skipped members - memberdocumenters: List[Tuple[Documenter, bool]] = [] + memberdocumenters: list[tuple[Documenter, bool]] = [] for (mname, member, isattr) in self.filter_members(members, want_all): classes = [cls for cls in self.documenters.values() if cls.can_document_member(member, mname, isattr, self)] @@ -819,8 +819,8 @@ class Documenter: self.env.temp_data['autodoc:module'] = None self.env.temp_data['autodoc:class'] = None - def sort_members(self, documenters: List[Tuple["Documenter", bool]], - order: str) -> List[Tuple["Documenter", bool]]: + def sort_members(self, documenters: list[tuple["Documenter", bool]], + order: str) -> list[tuple["Documenter", bool]]: """Sort the given member list.""" if order == 'groupwise': # sort by group; alphabetically within groups @@ -832,7 +832,7 @@ class Documenter: # sort by source order, by virtue of the module analyzer tagorder = self.analyzer.tagorder - def keyfunc(entry: Tuple[Documenter, bool]) -> int: + def keyfunc(entry: tuple[Documenter, bool]) -> int: fullname = entry[0].name.split('::')[1] return tagorder.get(fullname, len(tagorder)) documenters.sort(key=keyfunc) @@ -901,7 +901,7 @@ class Documenter: except PycodeError: pass - docstrings: List[str] = sum(self.get_doc() or [], []) + docstrings: list[str] = sum(self.get_doc() or [], []) if ismock(self.object) and not docstrings: logger.warning(__('A mocked object is detected: %r'), self.name, type='autodoc') @@ -981,7 +981,7 @@ class ModuleDocumenter(Documenter): return False def resolve_name(self, modname: str, parents: Any, path: str, base: Any - ) -> Tuple[str, List[str]]: + ) -> tuple[str, list[str]]: if modname is not None: logger.warning(__('"::" in automodule name doesn\'t make sense'), type='autodoc') @@ -1022,14 +1022,14 @@ class ModuleDocumenter(Documenter): if self.options.deprecated: self.add_line(' :deprecated:', sourcename) - def get_module_members(self) -> Dict[str, ObjectMember]: + def get_module_members(self) -> dict[str, ObjectMember]: """Get members of target module.""" if self.analyzer: attr_docs = self.analyzer.attr_docs else: attr_docs = {} - members: Dict[str, ObjectMember] = {} + members: dict[str, ObjectMember] = {} for name in dir(self.object): try: value = safe_getattr(self.object, name, None) @@ -1049,7 +1049,7 @@ class ModuleDocumenter(Documenter): return members - def get_object_members(self, want_all: bool) -> Tuple[bool, ObjectMembers]: + def get_object_members(self, want_all: bool) -> tuple[bool, ObjectMembers]: members = self.get_module_members() if want_all: if self.__all__ is None: @@ -1075,14 +1075,14 @@ class ModuleDocumenter(Documenter): type='autodoc') return False, ret - def sort_members(self, documenters: List[Tuple["Documenter", bool]], - order: str) -> List[Tuple["Documenter", bool]]: + def sort_members(self, documenters: list[tuple["Documenter", bool]], + order: str) -> list[tuple["Documenter", bool]]: if order == 'bysource' and self.__all__: # Sort alphabetically first (for members not listed on the __all__) documenters.sort(key=lambda e: e[0].name) # Sort by __all__ - def keyfunc(entry: Tuple[Documenter, bool]) -> int: + def keyfunc(entry: tuple[Documenter, bool]) -> int: name = entry[0].name.split('::')[1] if self.__all__ and name in self.__all__: return self.__all__.index(name) @@ -1101,7 +1101,7 @@ class ModuleLevelDocumenter(Documenter): classes, data/constants). """ def resolve_name(self, modname: str, parents: Any, path: str, base: Any - ) -> Tuple[str, List[str]]: + ) -> tuple[str, list[str]]: if modname is None: if path: modname = path.rstrip('.') @@ -1122,7 +1122,7 @@ class ClassLevelDocumenter(Documenter): attributes). """ def resolve_name(self, modname: str, parents: Any, path: str, base: Any - ) -> Tuple[str, List[str]]: + ) -> tuple[str, list[str]]: if modname is None: if path: mod_cls = path.rstrip('.') @@ -1154,10 +1154,10 @@ class DocstringSignatureMixin: Mixin for FunctionDocumenter and MethodDocumenter to provide the feature of reading the signature from the docstring. """ - _new_docstrings: List[List[str]] = None - _signatures: List[str] = None + _new_docstrings: list[list[str]] = None + _signatures: list[str] = None - def _find_signature(self) -> Tuple[Optional[str], Optional[str]]: + def _find_signature(self) -> tuple[Optional[str], Optional[str]]: # candidates of the object name valid_names = [self.objpath[-1]] # type: ignore if isinstance(self, ClassDocumenter): @@ -1208,7 +1208,7 @@ class DocstringSignatureMixin: return result - def get_doc(self) -> List[List[str]]: + def get_doc(self) -> list[list[str]]: if self._new_docstrings is not None: return self._new_docstrings return super().get_doc() # type: ignore[misc] @@ -1345,7 +1345,7 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ return overload.replace(parameters=parameters) - def annotate_to_first_argument(self, func: Callable, typ: Type) -> Optional[Callable]: + def annotate_to_first_argument(self, func: Callable, typ: type) -> Optional[Callable]: """Annotate type hint to the first argument of function if needed.""" try: sig = inspect.signature(func, type_aliases=self.config.autodoc_type_aliases) @@ -1455,7 +1455,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: self.doc_as_attr = True return ret - def _get_signature(self) -> Tuple[Optional[Any], Optional[str], Optional[Signature]]: + def _get_signature(self) -> tuple[Optional[Any], Optional[str], Optional[Signature]]: def get_user_defined_function_or_method(obj: Any, attr: str) -> Any: """ Get the `attr` function or method from `obj`, if it is user-defined. """ if inspect.is_builtin_class_method(obj, attr): @@ -1552,7 +1552,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: return stringify_signature(sig, show_return_annotation=False, **kwargs) - def _find_signature(self) -> Tuple[str, str]: + def _find_signature(self) -> tuple[str, str]: result = super()._find_signature() if result is not None: # Strip a return value from signature of constructor in docstring (first entry) @@ -1598,7 +1598,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: return "\n".join(sigs) - def get_overloaded_signatures(self) -> List[Signature]: + def get_overloaded_signatures(self) -> list[Signature]: if self._signature_class and self._signature_method_name: for cls in self._signature_class.__mro__: try: @@ -1667,7 +1667,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: self.add_line('', sourcename) self.add_line(' ' + _('Bases: %s') % ', '.join(base_classes), sourcename) - def get_object_members(self, want_all: bool) -> Tuple[bool, ObjectMembers]: + def get_object_members(self, want_all: bool) -> tuple[bool, ObjectMembers]: members = get_class_members(self.object, self.objpath, self.get_attr, self.config.autodoc_inherit_docstrings) if not want_all: @@ -1687,7 +1687,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: else: return False, [m for m in members.values() if m.class_ == self.object] - def get_doc(self) -> Optional[List[List[str]]]: + def get_doc(self) -> Optional[list[list[str]]]: if self.doc_as_attr: # Don't show the docstring of the class when it is an alias. comment = self.get_variable_comment() @@ -1739,7 +1739,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: tab_width = self.directive.state.document.settings.tab_width return [prepare_docstring(docstring, tab_width) for docstring in docstrings] - def get_variable_comment(self) -> Optional[List[str]]: + def get_variable_comment(self) -> Optional[list[str]]: try: key = ('', '.'.join(self.objpath)) if self.doc_as_attr: @@ -1817,7 +1817,7 @@ class DataDocumenterMixinBase: modname: str = None parent: Any = None object: Any = None - objpath: List[str] = None + objpath: list[str] = None def should_suppress_directive_header(self) -> bool: """Check directive header should be suppressed.""" @@ -1888,7 +1888,7 @@ class TypeVarMixin(DataDocumenterMixinBase): return (isinstance(self.object, TypeVar) or super().should_suppress_directive_header()) - def get_doc(self) -> Optional[List[List[str]]]: + def get_doc(self) -> Optional[list[list[str]]]: if isinstance(self.object, TypeVar): if self.object.__doc__ != TypeVar.__doc__: return super().get_doc() # type: ignore @@ -1956,7 +1956,7 @@ class UninitializedGlobalVariableMixin(DataDocumenterMixinBase): return (self.object is UNINITIALIZED_ATTR or super().should_suppress_value_header()) - def get_doc(self) -> Optional[List[List[str]]]: + def get_doc(self) -> Optional[list[list[str]]]: if self.object is UNINITIALIZED_ATTR: return [] else: @@ -2050,7 +2050,7 @@ class DataDocumenter(GenericAliasMixin, NewTypeMixin, TypeVarMixin, real_modname = self.get_attr(self.parent or self.object, '__module__', None) return real_modname or self.modname - def get_module_comment(self, attrname: str) -> Optional[List[str]]: + def get_module_comment(self, attrname: str) -> Optional[list[str]]: try: analyzer = ModuleAnalyzer.for_module(self.modname) analyzer.analyze() @@ -2062,7 +2062,7 @@ class DataDocumenter(GenericAliasMixin, NewTypeMixin, TypeVarMixin, return None - def get_doc(self) -> Optional[List[List[str]]]: + def get_doc(self) -> Optional[list[list[str]]]: # Check the variable has a docstring-comment comment = self.get_module_comment(self.objpath[-1]) if comment: @@ -2247,7 +2247,7 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type: return overload.replace(parameters=parameters) - def annotate_to_first_argument(self, func: Callable, typ: Type) -> Optional[Callable]: + def annotate_to_first_argument(self, func: Callable, typ: type) -> Optional[Callable]: """Annotate type hint to the first argument of function if needed.""" try: sig = inspect.signature(func, type_aliases=self.config.autodoc_type_aliases) @@ -2276,7 +2276,7 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type: return func - def get_doc(self) -> Optional[List[List[str]]]: + def get_doc(self) -> Optional[list[list[str]]]: if self._new_docstrings is not None: # docstring already returned previously, then modified by # `DocstringSignatureMixin`. Just return the previously-computed @@ -2335,7 +2335,7 @@ class NonDataDescriptorMixin(DataDocumenterMixinBase): return (not getattr(self, 'non_data_descriptor', False) or super().should_suppress_directive_header()) - def get_doc(self) -> Optional[List[List[str]]]: + def get_doc(self) -> Optional[list[list[str]]]: if getattr(self, 'non_data_descriptor', False): # the docstring of non datadescriptor is very probably the wrong thing # to display @@ -2373,7 +2373,7 @@ class SlotsMixin(DataDocumenterMixinBase): else: return super().should_suppress_value_header() - def get_doc(self) -> Optional[List[List[str]]]: + def get_doc(self) -> Optional[list[list[str]]]: if self.object is SLOTSATTR: try: __slots__ = inspect.getslots(self.parent) @@ -2462,7 +2462,7 @@ class RuntimeInstanceAttributeMixin(DataDocumenterMixinBase): return (self.object is self.RUNTIME_INSTANCE_ATTRIBUTE or super().should_suppress_value_header()) - def get_doc(self) -> Optional[List[List[str]]]: + def get_doc(self) -> Optional[list[list[str]]]: if (self.object is self.RUNTIME_INSTANCE_ATTRIBUTE and self.is_runtime_instance_attribute_not_commented(self.parent)): return None @@ -2518,7 +2518,7 @@ class UninitializedInstanceAttributeMixin(DataDocumenterMixinBase): return (self.object is UNINITIALIZED_ATTR or super().should_suppress_value_header()) - def get_doc(self) -> Optional[List[List[str]]]: + def get_doc(self) -> Optional[list[list[str]]]: if self.object is UNINITIALIZED_ATTR: return None else: @@ -2638,7 +2638,7 @@ class AttributeDocumenter(GenericAliasMixin, NewTypeMixin, SlotsMixin, # type: except ValueError: pass - def get_attribute_comment(self, parent: Any, attrname: str) -> Optional[List[str]]: + def get_attribute_comment(self, parent: Any, attrname: str) -> Optional[list[str]]: for cls in inspect.getmro(parent): try: module = safe_getattr(cls, '__module__') @@ -2655,7 +2655,7 @@ class AttributeDocumenter(GenericAliasMixin, NewTypeMixin, SlotsMixin, # type: return None - def get_doc(self) -> Optional[List[List[str]]]: + def get_doc(self) -> Optional[list[list[str]]]: # Check the attribute has a docstring-comment comment = self.get_attribute_comment(self.parent, self.objpath[-1]) if comment: @@ -2789,7 +2789,7 @@ def autodoc_attrgetter(app: Sphinx, obj: Any, name: str, *defargs: Any) -> Any: return safe_getattr(obj, name, *defargs) -def setup(app: Sphinx) -> Dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_autodocumenter(ModuleDocumenter) app.add_autodocumenter(ClassDocumenter) app.add_autodocumenter(ExceptionDocumenter) diff --git a/sphinx/ext/autodoc/directive.py b/sphinx/ext/autodoc/directive.py index 501912146..ff0a3eb05 100644 --- a/sphinx/ext/autodoc/directive.py +++ b/sphinx/ext/autodoc/directive.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Any, Callable, Dict, List, Optional, Set, Type +from typing import Any, Callable, Optional from docutils import nodes from docutils.nodes import Element, Node @@ -48,12 +48,12 @@ class DocumenterBridge: self._reporter = reporter self.genopt = options self.lineno = lineno - self.record_dependencies: Set[str] = set() + self.record_dependencies: set[str] = set() self.result = StringList() self.state = state -def process_documenter_options(documenter: Type[Documenter], config: Config, options: Dict +def process_documenter_options(documenter: type[Documenter], config: Config, options: dict ) -> Options: """Recognize options of Documenter from user input.""" for name in AUTODOC_DEFAULT_OPTIONS: @@ -80,7 +80,7 @@ def process_documenter_options(documenter: Type[Documenter], config: Config, opt def parse_generated_content(state: RSTState, content: StringList, documenter: Documenter - ) -> List[Node]: + ) -> list[Node]: """Parse an item of content generated by Documenter.""" with switch_source_input(state, content): if documenter.titles_allowed: @@ -108,7 +108,7 @@ class AutodocDirective(SphinxDirective): optional_arguments = 0 final_argument_whitespace = True - def run(self) -> List[Node]: + def run(self) -> list[Node]: reporter = self.state.document.reporter try: diff --git a/sphinx/ext/autodoc/importer.py b/sphinx/ext/autodoc/importer.py index bcd531486..b1c0b4ebd 100644 --- a/sphinx/ext/autodoc/importer.py +++ b/sphinx/ext/autodoc/importer.py @@ -5,7 +5,7 @@ from __future__ import annotations import importlib import traceback import warnings -from typing import TYPE_CHECKING, Any, Callable, Dict, List, NamedTuple, Optional +from typing import TYPE_CHECKING, Any, Callable, NamedTuple, Optional from sphinx.ext.autodoc.mock import ismock, undecorate from sphinx.pycode import ModuleAnalyzer, PycodeError @@ -64,7 +64,7 @@ def import_module(modname: str, warningiserror: bool = False) -> Any: raise ImportError(exc, traceback.format_exc()) from exc -def import_object(modname: str, objpath: List[str], objtype: str = '', +def import_object(modname: str, objpath: list[str], objtype: str = '', attrgetter: Callable[[Any, str], Any] = safe_getattr, warningiserror: bool = False) -> Any: if objpath: @@ -145,17 +145,17 @@ class Attribute(NamedTuple): def get_object_members( subject: Any, - objpath: List[str], + objpath: list[str], attrgetter: Callable, analyzer: Optional[ModuleAnalyzer] = None -) -> Dict[str, Attribute]: +) -> dict[str, Attribute]: """Get members and attributes of target object.""" from sphinx.ext.autodoc import INSTANCEATTR # the members directly defined in the class obj_dict = attrgetter(subject, '__dict__', {}) - members: Dict[str, Attribute] = {} + members: dict[str, Attribute] = {} # enum members if isenumclass(subject): @@ -208,15 +208,15 @@ def get_object_members( return members -def get_class_members(subject: Any, objpath: List[str], attrgetter: Callable, - inherit_docstrings: bool = True) -> Dict[str, "ObjectMember"]: +def get_class_members(subject: Any, objpath: list[str], attrgetter: Callable, + inherit_docstrings: bool = True) -> dict[str, "ObjectMember"]: """Get members and attributes of target class.""" from sphinx.ext.autodoc import INSTANCEATTR, ObjectMember # the members directly defined in the class obj_dict = attrgetter(subject, '__dict__', {}) - members: Dict[str, ObjectMember] = {} + members: dict[str, ObjectMember] = {} # enum members if isenumclass(subject): diff --git a/sphinx/ext/autodoc/mock.py b/sphinx/ext/autodoc/mock.py index 0747508eb..b5690236f 100644 --- a/sphinx/ext/autodoc/mock.py +++ b/sphinx/ext/autodoc/mock.py @@ -8,7 +8,7 @@ import sys from importlib.abc import Loader, MetaPathFinder from importlib.machinery import ModuleSpec from types import MethodType, ModuleType -from typing import Any, Generator, Iterator, List, Optional, Sequence, Tuple, Union +from typing import Any, Generator, Iterator, Optional, Sequence, Union from sphinx.util import logging from sphinx.util.inspect import isboundmethod, safe_getattr @@ -22,7 +22,7 @@ class _MockObject: __display_name__ = '_MockObject' __name__ = '' __sphinx_mock__ = True - __sphinx_decorator_args__: Tuple[Any, ...] = () + __sphinx_decorator_args__: tuple[Any, ...] = () def __new__(cls, *args: Any, **kwargs: Any) -> Any: if len(args) == 3 and isinstance(args[1], tuple): @@ -46,7 +46,7 @@ class _MockObject: def __iter__(self) -> Iterator: return iter([]) - def __mro_entries__(self, bases: Tuple) -> Tuple: + def __mro_entries__(self, bases: tuple) -> tuple: return (self.__class__,) def __getitem__(self, key: Any) -> "_MockObject": @@ -65,7 +65,7 @@ class _MockObject: def _make_subclass(name: str, module: str, superclass: Any = _MockObject, - attributes: Any = None, decorator_args: Tuple = ()) -> Any: + attributes: Any = None, decorator_args: tuple = ()) -> Any: attrs = {'__module__': module, '__display_name__': module + '.' + name, '__name__': name, @@ -82,8 +82,8 @@ class _MockModule(ModuleType): def __init__(self, name: str) -> None: super().__init__(name) - self.__all__: List[str] = [] - self.__path__: List[str] = [] + self.__all__: list[str] = [] + self.__path__: list[str] = [] def __getattr__(self, name: str) -> _MockObject: return _make_subclass(name, self.__name__)() @@ -110,11 +110,11 @@ class MockLoader(Loader): class MockFinder(MetaPathFinder): """A finder for mocking.""" - def __init__(self, modnames: List[str]) -> None: + def __init__(self, modnames: list[str]) -> None: super().__init__() self.modnames = modnames self.loader = MockLoader(self) - self.mocked_modules: List[str] = [] + self.mocked_modules: list[str] = [] def find_spec(self, fullname: str, path: Optional[Sequence[Union[bytes, str]]], target: ModuleType = None) -> Optional[ModuleSpec]: @@ -132,7 +132,7 @@ class MockFinder(MetaPathFinder): @contextlib.contextmanager -def mock(modnames: List[str]) -> Generator[None, None, None]: +def mock(modnames: list[str]) -> Generator[None, None, None]: """Insert mock modules during context:: with mock(['target.module.name']): diff --git a/sphinx/ext/autodoc/preserve_defaults.py b/sphinx/ext/autodoc/preserve_defaults.py index 7c5dfb7f1..3c455f76b 100644 --- a/sphinx/ext/autodoc/preserve_defaults.py +++ b/sphinx/ext/autodoc/preserve_defaults.py @@ -8,7 +8,7 @@ from __future__ import annotations import ast import inspect -from typing import Any, Dict, List, Optional +from typing import Any, Optional import sphinx from sphinx.application import Sphinx @@ -46,7 +46,7 @@ def get_function_def(obj: Any) -> Optional[ast.FunctionDef]: return None -def get_default_value(lines: List[str], position: ast.AST) -> Optional[str]: +def get_default_value(lines: list[str], position: ast.AST) -> Optional[str]: try: if position.lineno == position.end_lineno: line = lines[position.lineno - 1] @@ -114,7 +114,7 @@ def update_defvalue(app: Sphinx, obj: Any, bound_method: bool) -> None: logger.warning(__("Failed to parse a default argument value for %r: %s"), obj, exc) -def setup(app: Sphinx) -> Dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_config_value('autodoc_preserve_defaults', False, True) app.connect('autodoc-before-process-signature', update_defvalue) diff --git a/sphinx/ext/autodoc/type_comment.py b/sphinx/ext/autodoc/type_comment.py index edb01e5d9..e8e5cc2da 100644 --- a/sphinx/ext/autodoc/type_comment.py +++ b/sphinx/ext/autodoc/type_comment.py @@ -4,7 +4,7 @@ from __future__ import annotations import ast from inspect import Parameter, Signature, getsource -from typing import Any, Dict, List, Optional, cast +from typing import Any, Optional, cast import sphinx from sphinx.application import Sphinx @@ -15,7 +15,7 @@ from sphinx.util import inspect, logging logger = logging.getLogger(__name__) -def not_suppressed(argtypes: List[ast.AST] = []) -> bool: +def not_suppressed(argtypes: list[ast.AST] = []) -> bool: """Check given *argtypes* is suppressed type_comment or not.""" if len(argtypes) == 0: # no argtypees return False @@ -125,7 +125,7 @@ def update_annotations_using_type_comments(app: Sphinx, obj: Any, bound_method: logger.warning(__("Failed to parse type_comment for %r: %s"), obj, exc) -def setup(app: Sphinx) -> Dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.connect('autodoc-before-process-signature', update_annotations_using_type_comments) return {'version': sphinx.__display_version__, 'parallel_read_safe': True} diff --git a/sphinx/ext/autodoc/typehints.py b/sphinx/ext/autodoc/typehints.py index 9e30c308e..905bfc2af 100644 --- a/sphinx/ext/autodoc/typehints.py +++ b/sphinx/ext/autodoc/typehints.py @@ -4,7 +4,7 @@ from __future__ import annotations import re from collections import OrderedDict -from typing import Any, Dict, Iterable, Set, cast +from typing import Any, Iterable, cast from docutils import nodes from docutils.nodes import Element @@ -16,7 +16,7 @@ from sphinx.util import inspect, typing def record_typehints(app: Sphinx, objtype: str, name: str, obj: Any, - options: Dict, args: str, retann: str) -> None: + options: dict, args: str, retann: str) -> None: """Record type hints to env object.""" if app.config.autodoc_typehints_format == 'short': mode = 'smart' @@ -89,9 +89,9 @@ def insert_field_list(node: Element) -> nodes.field_list: return field_list -def modify_field_list(node: nodes.field_list, annotations: Dict[str, str], +def modify_field_list(node: nodes.field_list, annotations: dict[str, str], suppress_rtype: bool = False) -> None: - arguments: Dict[str, Dict[str, bool]] = {} + arguments: dict[str, dict[str, bool]] = {} fields = cast(Iterable[nodes.field], node) for field in fields: field_name = field[0].astext() @@ -151,12 +151,12 @@ def modify_field_list(node: nodes.field_list, annotations: Dict[str, str], def augment_descriptions_with_types( node: nodes.field_list, - annotations: Dict[str, str], + annotations: dict[str, str], force_rtype: bool ) -> None: fields = cast(Iterable[nodes.field], node) - has_description: Set[str] = set() - has_type: Set[str] = set() + has_description: set[str] = set() + has_type: set[str] = set() for field in fields: field_name = field[0].astext() parts = re.split(' +', field_name) @@ -204,7 +204,7 @@ def augment_descriptions_with_types( node += field -def setup(app: Sphinx) -> Dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.connect('autodoc-process-signature', record_typehints) app.connect('object-description-transform', merge_typehints) diff --git a/sphinx/ext/autosectionlabel.py b/sphinx/ext/autosectionlabel.py index dee219cd2..d8e7854d0 100644 --- a/sphinx/ext/autosectionlabel.py +++ b/sphinx/ext/autosectionlabel.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Any, Dict, cast +from typing import Any, cast from docutils import nodes from docutils.nodes import Node @@ -54,7 +54,7 @@ def register_sections_as_label(app: Sphinx, document: Node) -> None: domain.labels[name] = docname, labelid, sectname -def setup(app: Sphinx) -> Dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_config_value('autosectionlabel_prefix_document', False, 'env') app.add_config_value('autosectionlabel_maxdepth', None, 'env') app.connect('doctree-read', register_sections_as_label) diff --git a/sphinx/ext/autosummary/__init__.py b/sphinx/ext/autosummary/__init__.py index b5ab99d63..f169b2416 100644 --- a/sphinx/ext/autosummary/__init__.py +++ b/sphinx/ext/autosummary/__init__.py @@ -57,7 +57,7 @@ import warnings from inspect import Parameter from os import path from types import ModuleType -from typing import Any, Dict, List, Optional, Sequence, Tuple, Type, cast +from typing import Any, List, Optional, Sequence, cast from docutils import nodes from docutils.nodes import Node, system_message @@ -142,7 +142,7 @@ class FakeApplication: def __init__(self) -> None: self.doctreedir = None self.events = None - self.extensions: Dict[str, Extension] = {} + self.extensions: dict[str, Extension] = {} self.srcdir = None self.config = Config() self.project = Project(None, None) @@ -160,7 +160,7 @@ class FakeDirective(DocumenterBridge): super().__init__(env, None, Options(), 0, state) -def get_documenter(app: Sphinx, obj: Any, parent: Any) -> Type[Documenter]: +def get_documenter(app: Sphinx, obj: Any, parent: Any) -> type[Documenter]: """Get an autodoc.Documenter class suitable for documenting the given object. @@ -216,7 +216,7 @@ class Autosummary(SphinxDirective): 'template': directives.unchanged, } - def run(self) -> List[Node]: + def run(self) -> list[Node]: self.bridge = DocumenterBridge(self.env, self.state.document.reporter, Options(), self.lineno, self.state) @@ -265,8 +265,8 @@ class Autosummary(SphinxDirective): return nodes def import_by_name( - self, name: str, prefixes: List[Optional[str]] - ) -> Tuple[str, Any, Any, str]: + self, name: str, prefixes: list[Optional[str]] + ) -> tuple[str, Any, Any, str]: with mock(self.config.autosummary_mock_imports): try: return import_by_name(name, prefixes) @@ -276,7 +276,7 @@ class Autosummary(SphinxDirective): return import_ivar_by_name(name, prefixes) except ImportError as exc2: if exc2.__cause__: - errors: List[BaseException] = exc.exceptions + [exc2.__cause__] + errors: list[BaseException] = exc.exceptions + [exc2.__cause__] else: errors = exc.exceptions + [exc2] @@ -292,13 +292,13 @@ class Autosummary(SphinxDirective): doccls = get_documenter(app, obj, parent) return doccls(self.bridge, full_name) - def get_items(self, names: List[str]) -> List[Tuple[str, str, str, str]]: + def get_items(self, names: list[str]) -> list[tuple[str, str, str, str]]: """Try to import the given names, and return a list of ``[(name, signature, summary_string, real_name), ...]``. """ prefixes = get_import_prefixes_from_env(self.env) - items: List[Tuple[str, str, str, str]] = [] + items: list[tuple[str, str, str, str]] = [] max_item_chars = 50 @@ -374,7 +374,7 @@ class Autosummary(SphinxDirective): return items - def get_table(self, items: List[Tuple[str, str, str, str]]) -> List[Node]: + def get_table(self, items: list[tuple[str, str, str, str]]) -> list[Node]: """Generate a proper list of table nodes for autosummary:: directive. *items* is a list produced by :meth:`get_items`. @@ -472,8 +472,8 @@ def mangle_signature(sig: str, max_chars: int = 30) -> str: s = re.sub(r'{[^}]*}', '', s) # Parse the signature to arguments + options - args: List[str] = [] - opts: List[str] = [] + args: list[str] = [] + opts: list[str] = [] opt_re = re.compile(r"^(.*, |)([a-zA-Z0-9_*]+)\s*=\s*") while s: @@ -505,9 +505,9 @@ def mangle_signature(sig: str, max_chars: int = 30) -> str: return "(%s)" % sig -def extract_summary(doc: List[str], document: Any) -> str: +def extract_summary(doc: list[str], document: Any) -> str: """Extract summary from docstring.""" - def parse(doc: List[str], settings: Any) -> nodes.document: + def parse(doc: list[str], settings: Any) -> nodes.document: state_machine = RSTStateMachine(state_classes, 'Body') node = new_document('', settings) node.reporter = NullReporter() @@ -561,7 +561,7 @@ def extract_summary(doc: List[str], document: Any) -> str: return summary -def limited_join(sep: str, items: List[str], max_chars: int = 30, +def limited_join(sep: str, items: list[str], max_chars: int = 30, overflow_marker: str = "...") -> str: """Join a number of strings into one, limiting the length to *max_chars*. @@ -600,12 +600,12 @@ class ImportExceptionGroup(Exception): self.exceptions = list(exceptions) -def get_import_prefixes_from_env(env: BuildEnvironment) -> List[Optional[str]]: +def get_import_prefixes_from_env(env: BuildEnvironment) -> list[Optional[str]]: """ Obtain current Python import prefixes (for `import_by_name`) from ``document.env`` """ - prefixes: List[Optional[str]] = [None] + prefixes: list[Optional[str]] = [None] currmodule = env.ref_context.get('py:module') if currmodule: @@ -622,8 +622,8 @@ def get_import_prefixes_from_env(env: BuildEnvironment) -> List[Optional[str]]: def import_by_name( - name: str, prefixes: List[Optional[str]] = [None], grouped_exception: bool = True -) -> Tuple[str, Any, Any, str]: + name: str, prefixes: list[Optional[str]] = [None], grouped_exception: bool = True +) -> tuple[str, Any, Any, str]: """Import a Python object that has the given *name*, under one of the *prefixes*. The first name that succeeds is used. """ @@ -634,7 +634,7 @@ def import_by_name( RemovedInSphinx70Warning, stacklevel=2) tried = [] - errors: List[ImportExceptionGroup] = [] + errors: list[ImportExceptionGroup] = [] for prefix in prefixes: try: if prefix: @@ -650,15 +650,15 @@ def import_by_name( errors.append(exc) if grouped_exception: - exceptions: List[BaseException] = sum((e.exceptions for e in errors), []) + exceptions: list[BaseException] = sum((e.exceptions for e in errors), []) raise ImportExceptionGroup('no module named %s' % ' or '.join(tried), exceptions) else: raise ImportError('no module named %s' % ' or '.join(tried)) -def _import_by_name(name: str, grouped_exception: bool = True) -> Tuple[Any, Any, str]: +def _import_by_name(name: str, grouped_exception: bool = True) -> tuple[Any, Any, str]: """Import a Python object given its full name.""" - errors: List[BaseException] = [] + errors: list[BaseException] = [] try: name_parts = name.split('.') @@ -703,8 +703,8 @@ def _import_by_name(name: str, grouped_exception: bool = True) -> Tuple[Any, Any raise ImportError(*exc.args) from exc -def import_ivar_by_name(name: str, prefixes: List[Optional[str]] = [None], - grouped_exception: bool = True) -> Tuple[str, Any, Any, str]: +def import_ivar_by_name(name: str, prefixes: list[Optional[str]] = [None], + grouped_exception: bool = True) -> tuple[str, Any, Any, str]: """Import an instance variable that has the given *name*, under one of the *prefixes*. The first name that succeeds is used. """ @@ -733,7 +733,7 @@ class AutoLink(SphinxRole): Expands to ':obj:`text`' if `text` is an object that can be imported; otherwise expands to '*text*'. """ - def run(self) -> Tuple[List[Node], List[system_message]]: + def run(self) -> tuple[list[Node], list[system_message]]: pyobj_role = self.env.get_domain('py').role('obj') objects, errors = pyobj_role('obj', self.rawtext, self.text, self.lineno, self.inliner, self.options, self.content) @@ -755,7 +755,7 @@ class AutoLink(SphinxRole): def get_rst_suffix(app: Sphinx) -> Optional[str]: - def get_supported_format(suffix: str) -> Tuple[str, ...]: + def get_supported_format(suffix: str) -> tuple[str, ...]: parser_class = app.registry.get_source_parsers().get(suffix) if parser_class is None: return ('restructuredtext',) @@ -807,7 +807,7 @@ def process_generate_options(app: Sphinx) -> None: encoding=app.config.source_encoding) -def setup(app: Sphinx) -> Dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: # I need autodoc app.setup_extension('sphinx.ext.autodoc') app.add_node(autosummary_toc, diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py index 9a00cf518..4322c64d2 100644 --- a/sphinx/ext/autosummary/generate.py +++ b/sphinx/ext/autosummary/generate.py @@ -24,7 +24,7 @@ import re import sys from gettext import NullTranslations from os import path -from typing import Any, Dict, List, NamedTuple, Optional, Sequence, Set, Tuple, Type +from typing import Any, NamedTuple, Optional, Sequence from jinja2 import TemplateNotFound from jinja2.sandbox import SandboxedEnvironment @@ -55,7 +55,7 @@ class DummyApplication: def __init__(self, translator: NullTranslations) -> None: self.config = Config() self.registry = SphinxComponentRegistry() - self.messagelog: List[str] = [] + self.messagelog: list[str] = [] self.srcdir = "/" self.translator = translator self.verbosity = 0 @@ -84,7 +84,7 @@ def setup_documenters(app: Any) -> None: FunctionDocumenter, MethodDocumenter, ModuleDocumenter, NewTypeAttributeDocumenter, NewTypeDataDocumenter, PropertyDocumenter) - documenters: List[Type[Documenter]] = [ + documenters: list[type[Documenter]] = [ ModuleDocumenter, ClassDocumenter, ExceptionDocumenter, DataDocumenter, FunctionDocumenter, MethodDocumenter, NewTypeAttributeDocumenter, NewTypeDataDocumenter, AttributeDocumenter, DecoratorDocumenter, PropertyDocumenter, @@ -119,7 +119,7 @@ class AutosummaryRenderer: self.env.add_extension("jinja2.ext.i18n") self.env.install_gettext_translations(app.translator) - def render(self, template_name: str, context: Dict) -> str: + def render(self, template_name: str, context: dict) -> str: """Render a template file.""" try: template = self.env.get_template(template_name) @@ -155,7 +155,7 @@ class ModuleScanner: name, exc, type='autosummary') return False - def scan(self, imported_members: bool) -> List[str]: + def scan(self, imported_members: bool) -> list[str]: members = [] try: analyzer = ModuleAnalyzer.for_module(self.object.__name__) @@ -213,7 +213,7 @@ def members_of(obj: Any, conf: Config) -> Sequence[str]: def generate_autosummary_content(name: str, obj: Any, parent: Any, template: AutosummaryRenderer, template_name: str, imported_members: bool, app: Any, - recursive: bool, context: Dict, + recursive: bool, context: dict, modname: Optional[str] = None, qualname: Optional[str] = None) -> str: doc = get_documenter(app, obj, parent) @@ -228,11 +228,11 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any, name, exc, type='autosummary') return False - def get_class_members(obj: Any) -> Dict[str, Any]: + def get_class_members(obj: Any) -> dict[str, Any]: members = sphinx.ext.autodoc.get_class_members(obj, [qualname], safe_getattr) return {name: member.object for name, member in members.items()} - def get_module_members(obj: Any) -> Dict[str, Any]: + def get_module_members(obj: Any) -> dict[str, Any]: members = {} for name in members_of(obj, app.config): try: @@ -241,17 +241,17 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any, continue return members - def get_all_members(obj: Any) -> Dict[str, Any]: + def get_all_members(obj: Any) -> dict[str, Any]: if doc.objtype == "module": return get_module_members(obj) elif doc.objtype == "class": return get_class_members(obj) return {} - def get_members(obj: Any, types: Set[str], include_public: List[str] = [], - imported: bool = True) -> Tuple[List[str], List[str]]: - items: List[str] = [] - public: List[str] = [] + def get_members(obj: Any, types: set[str], include_public: list[str] = [], + imported: bool = True) -> tuple[list[str], list[str]]: + items: list[str] = [] + public: list[str] = [] all_members = get_all_members(obj) for name, value in all_members.items(): @@ -273,7 +273,7 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any, public.append(name) return public, items - def get_module_attrs(members: Any) -> Tuple[List[str], List[str]]: + def get_module_attrs(members: Any) -> tuple[list[str], list[str]]: """Find module attributes with docstrings.""" attrs, public = [], [] try: @@ -288,8 +288,8 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any, pass # give up if ModuleAnalyzer fails to parse code return public, attrs - def get_modules(obj: Any) -> Tuple[List[str], List[str]]: - items: List[str] = [] + def get_modules(obj: Any) -> tuple[list[str], list[str]]: + items: list[str] = [] for _, modname, _ispkg in pkgutil.iter_modules(obj.__path__): fullname = name + '.' + modname try: @@ -303,7 +303,7 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any, public = [x for x in items if not x.split('.')[-1].startswith('_')] return public, items - ns: Dict[str, Any] = {} + ns: dict[str, Any] = {} ns.update(context) if doc.objtype == 'module': @@ -354,7 +354,7 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any, return template.render(doc.objtype, ns) -def generate_autosummary_docs(sources: List[str], output_dir: Optional[str] = None, +def generate_autosummary_docs(sources: list[str], output_dir: Optional[str] = None, suffix: str = '.rst', base_path: Optional[str] = None, imported_members: bool = False, app: Any = None, overwrite: bool = True, encoding: str = 'utf-8') -> None: @@ -403,7 +403,7 @@ def generate_autosummary_docs(sources: List[str], output_dir: Optional[str] = No qualname = name.replace(modname + ".", "") except ImportError as exc2: if exc2.__cause__: - exceptions: List[BaseException] = exc.exceptions + [exc2.__cause__] + exceptions: list[BaseException] = exc.exceptions + [exc2.__cause__] else: exceptions = exc.exceptions + [exc2] @@ -412,7 +412,7 @@ def generate_autosummary_docs(sources: List[str], output_dir: Optional[str] = No entry.name, '\n'.join(errors)) continue - context: Dict[str, Any] = {} + context: dict[str, Any] = {} if app: context.update(app.config.autosummary_context) @@ -446,12 +446,12 @@ def generate_autosummary_docs(sources: List[str], output_dir: Optional[str] = No # -- Finding documented entries in files --------------------------------------- -def find_autosummary_in_files(filenames: List[str]) -> List[AutosummaryEntry]: +def find_autosummary_in_files(filenames: list[str]) -> list[AutosummaryEntry]: """Find out what items are documented in source/*.rst. See `find_autosummary_in_lines`. """ - documented: List[AutosummaryEntry] = [] + documented: list[AutosummaryEntry] = [] for filename in filenames: with open(filename, encoding='utf-8', errors='ignore') as f: lines = f.read().splitlines() @@ -461,7 +461,7 @@ def find_autosummary_in_files(filenames: List[str]) -> List[AutosummaryEntry]: def find_autosummary_in_docstring( name: str, filename: Optional[str] = None -) -> List[AutosummaryEntry]: +) -> list[AutosummaryEntry]: """Find out what items are documented in the given object's docstring. See `find_autosummary_in_lines`. @@ -482,8 +482,8 @@ def find_autosummary_in_docstring( def find_autosummary_in_lines( - lines: List[str], module: Optional[str] = None, filename: Optional[str] = None -) -> List[AutosummaryEntry]: + lines: list[str], module: Optional[str] = None, filename: Optional[str] = None +) -> list[AutosummaryEntry]: """Find out what items appear in autosummary:: directives in the given lines. @@ -504,7 +504,7 @@ def find_autosummary_in_lines( toctree_arg_re = re.compile(r'^\s+:toctree:\s*(.*?)\s*$') template_arg_re = re.compile(r'^\s+:template:\s*(.*?)\s*$') - documented: List[AutosummaryEntry] = [] + documented: list[AutosummaryEntry] = [] recursive = False toctree: Optional[str] = None @@ -623,7 +623,7 @@ The format of the autosummary directive is documented in the return parser -def main(argv: List[str] = sys.argv[1:]) -> None: +def main(argv: list[str] = sys.argv[1:]) -> None: sphinx.locale.setlocale(locale.LC_ALL, '') sphinx.locale.init_console(os.path.join(package_dir, 'locale'), 'sphinx') translator, _ = sphinx.locale.init([], None) diff --git a/sphinx/ext/coverage.py b/sphinx/ext/coverage.py index 72e6e0b67..da2a72b54 100644 --- a/sphinx/ext/coverage.py +++ b/sphinx/ext/coverage.py @@ -12,7 +12,7 @@ import pickle import re from importlib import import_module from os import path -from typing import IO, Any, Dict, List, Pattern, Set, Tuple +from typing import IO, Any import sphinx from sphinx.application import Sphinx @@ -31,7 +31,7 @@ def write_header(f: IO[str], text: str, char: str = '-') -> None: f.write(char * len(text) + '\n') -def compile_regex_list(name: str, exps: str) -> List[Pattern[str]]: +def compile_regex_list(name: str, exps: str) -> list[re.Pattern[str]]: lst = [] for exp in exps: try: @@ -50,19 +50,19 @@ class CoverageBuilder(Builder): 'results in %(outdir)s' + path.sep + 'python.txt.') def init(self) -> None: - self.c_sourcefiles: List[str] = [] + self.c_sourcefiles: list[str] = [] for pattern in self.config.coverage_c_path: pattern = path.join(self.srcdir, pattern) self.c_sourcefiles.extend(glob.glob(pattern)) - self.c_regexes: List[Tuple[str, Pattern[str]]] = [] + self.c_regexes: list[tuple[str, re.Pattern[str]]] = [] for (name, exp) in self.config.coverage_c_regexes.items(): try: self.c_regexes.append((name, re.compile(exp))) except Exception: logger.warning(__('invalid regex %r in coverage_c_regexes'), exp) - self.c_ignorexps: Dict[str, List[Pattern[str]]] = {} + self.c_ignorexps: dict[str, list[re.Pattern[str]]] = {} for (name, exps) in self.config.coverage_ignore_c_items.items(): self.c_ignorexps[name] = compile_regex_list('coverage_ignore_c_items', exps) @@ -79,11 +79,11 @@ class CoverageBuilder(Builder): return 'coverage overview' def write(self, *ignored: Any) -> None: - self.py_undoc: Dict[str, Dict[str, Any]] = {} + self.py_undoc: dict[str, dict[str, Any]] = {} self.build_py_coverage() self.write_py_coverage() - self.c_undoc: Dict[str, Set[Tuple[str, str]]] = {} + self.c_undoc: dict[str, set[tuple[str, str]]] = {} self.build_c_coverage() self.write_c_coverage() @@ -91,7 +91,7 @@ class CoverageBuilder(Builder): # Fetch all the info from the header files c_objects = self.env.domaindata['c']['objects'] for filename in self.c_sourcefiles: - undoc: Set[Tuple[str, str]] = set() + undoc: set[tuple[str, str]] = set() with open(filename, encoding="utf-8") as f: for line in f: for key, regex in self.c_regexes: @@ -158,7 +158,7 @@ class CoverageBuilder(Builder): continue funcs = [] - classes: Dict[str, List[str]] = {} + classes: dict[str, list[str]] = {} for name, obj in inspect.getmembers(mod): # diverse module attributes are ignored: @@ -197,7 +197,7 @@ class CoverageBuilder(Builder): classes[name] = [] continue - attrs: List[str] = [] + attrs: list[str] = [] for attr_name in dir(obj): if attr_name not in obj.__dict__: @@ -300,7 +300,7 @@ class CoverageBuilder(Builder): pickle.dump((self.py_undoc, self.c_undoc), dumpfile) -def setup(app: Sphinx) -> Dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_builder(CoverageBuilder) app.add_config_value('coverage_ignore_modules', [], False) app.add_config_value('coverage_ignore_functions', [], False) diff --git a/sphinx/ext/doctest.py b/sphinx/ext/doctest.py index 5d60b627e..7eeb5e0d3 100644 --- a/sphinx/ext/doctest.py +++ b/sphinx/ext/doctest.py @@ -11,8 +11,7 @@ import sys import time from io import StringIO from os import path -from typing import (TYPE_CHECKING, Any, Callable, Dict, Iterable, List, Optional, Sequence, - Set, Tuple, Type) +from typing import TYPE_CHECKING, Any, Callable, Iterable, Optional, Sequence from docutils import nodes from docutils.nodes import Element, Node, TextElement @@ -69,7 +68,7 @@ class TestDirective(SphinxDirective): optional_arguments = 1 final_argument_whitespace = True - def run(self) -> List[Node]: + def run(self) -> list[Node]: # use ordinary docutils nodes for test code: they get special attributes # so that our builder recognizes them, and the other builders are happy. code = '\n'.join(self.content) @@ -83,7 +82,7 @@ class TestDirective(SphinxDirective): if not test: test = code code = doctestopt_re.sub('', code) - nodetype: Type[TextElement] = nodes.literal_block + nodetype: type[TextElement] = nodes.literal_block if self.name in ('testsetup', 'testcleanup') or 'hide' in self.options: nodetype = nodes.comment if self.arguments: @@ -192,9 +191,9 @@ parser = doctest.DocTestParser() class TestGroup: def __init__(self, name: str) -> None: self.name = name - self.setup: List[TestCode] = [] - self.tests: List[List[TestCode]] = [] - self.cleanup: List[TestCode] = [] + self.setup: list[TestCode] = [] + self.tests: list[list[TestCode]] = [] + self.cleanup: list[TestCode] = [] def add_code(self, code: "TestCode", prepend: bool = False) -> None: if code.type == 'testsetup': @@ -221,7 +220,7 @@ class TestGroup: class TestCode: def __init__(self, code: str, type: str, filename: str, - lineno: int, options: Optional[Dict] = None) -> None: + lineno: int, options: Optional[dict] = None) -> None: self.code = code self.type = type self.filename = filename @@ -235,7 +234,7 @@ class TestCode: class SphinxDocTestRunner(doctest.DocTestRunner): def summarize(self, out: Callable, verbose: bool = None # type: ignore - ) -> Tuple[int, int]: + ) -> tuple[int, int]: string_io = StringIO() old_stdout = sys.stdout sys.stdout = string_io @@ -316,7 +315,7 @@ class DocTestBuilder(Builder): def get_target_uri(self, docname: str, typ: Optional[str] = None) -> str: return '' - def get_outdated_docs(self) -> Set[str]: + def get_outdated_docs(self) -> set[str]: return self.env.found_docs def finish(self) -> None: @@ -382,7 +381,7 @@ Doctest summary return False else: condition = node['skipif'] - context: Dict[str, Any] = {} + context: dict[str, Any] = {} if self.config.doctest_global_setup: exec(self.config.doctest_global_setup, context) # NoQA: S102 should_skip = eval(condition, context) # NoQA: PGH001 @@ -391,7 +390,7 @@ Doctest summary return should_skip def test_doc(self, docname: str, doctree: Node) -> None: - groups: Dict[str, TestGroup] = {} + groups: dict[str, TestGroup] = {} add_to_all_groups = [] self.setup_runner = SphinxDocTestRunner(verbose=False, optionflags=self.opt) @@ -472,9 +471,9 @@ Doctest summary return compile(code, name, self.type, flags, dont_inherit) def test_group(self, group: TestGroup) -> None: - ns: Dict = {} + ns: dict = {} - def run_setup_cleanup(runner: Any, testcodes: List[TestCode], what: Any) -> bool: + def run_setup_cleanup(runner: Any, testcodes: list[TestCode], what: Any) -> bool: examples = [] for testcode in testcodes: example = doctest.Example(testcode.code, '', lineno=testcode.lineno) @@ -543,7 +542,7 @@ Doctest summary run_setup_cleanup(self.cleanup_runner, group.cleanup, 'cleanup') -def setup(app: "Sphinx") -> Dict[str, Any]: +def setup(app: "Sphinx") -> dict[str, Any]: app.add_directive('testsetup', TestsetupDirective) app.add_directive('testcleanup', TestcleanupDirective) app.add_directive('doctest', DoctestDirective) diff --git a/sphinx/ext/duration.py b/sphinx/ext/duration.py index 69909c29b..749e2910b 100644 --- a/sphinx/ext/duration.py +++ b/sphinx/ext/duration.py @@ -5,7 +5,7 @@ from __future__ import annotations from datetime import datetime, timedelta from itertools import islice from operator import itemgetter -from typing import Any, Dict, List, cast +from typing import Any, cast from docutils import nodes @@ -23,7 +23,7 @@ class DurationDomain(Domain): name = 'duration' @property - def reading_durations(self) -> Dict[str, timedelta]: + def reading_durations(self) -> dict[str, timedelta]: return self.data.setdefault('reading_durations', {}) def note_reading_duration(self, duration: timedelta) -> None: @@ -35,7 +35,7 @@ class DurationDomain(Domain): def clear_doc(self, docname: str) -> None: self.reading_durations.pop(docname, None) - def merge_domaindata(self, docnames: List[str], otherdata: Dict[str, timedelta]) -> None: + def merge_domaindata(self, docnames: list[str], otherdata: dict[str, timedelta]) -> None: for docname, duration in otherdata.items(): if docname in docnames: self.reading_durations[docname] = duration @@ -50,7 +50,7 @@ def on_builder_inited(app: Sphinx) -> None: domain.clear() -def on_source_read(app: Sphinx, docname: str, content: List[str]) -> None: +def on_source_read(app: Sphinx, docname: str, content: list[str]) -> None: """Start to measure reading duration.""" app.env.temp_data['started_at'] = datetime.now() @@ -76,7 +76,7 @@ def on_build_finished(app: Sphinx, error: Exception) -> None: logger.info('%d.%03d %s', d.seconds, d.microseconds / 1000, docname) -def setup(app: Sphinx) -> Dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_domain(DurationDomain) app.connect('builder-inited', on_builder_inited) app.connect('source-read', on_source_read) diff --git a/sphinx/ext/extlinks.py b/sphinx/ext/extlinks.py index 78ffd8dc0..26fd36cc7 100644 --- a/sphinx/ext/extlinks.py +++ b/sphinx/ext/extlinks.py @@ -20,7 +20,7 @@ Both, the url string and the caption string must escape ``%`` as ``%%``. from __future__ import annotations import re -from typing import Any, Dict, List, Tuple +from typing import Any from docutils import nodes, utils from docutils.nodes import Node, system_message @@ -91,8 +91,8 @@ def make_link_role(name: str, base_url: str, caption: str) -> RoleFunction: # Remark: It is an implementation detail that we use Pythons %-formatting. # So far we only expose ``%s`` and require quoting of ``%`` using ``%%``. def role(typ: str, rawtext: str, text: str, lineno: int, - inliner: Inliner, options: Dict = {}, content: List[str] = [] - ) -> Tuple[List[Node], List[system_message]]: + inliner: Inliner, options: dict = {}, content: list[str] = [] + ) -> tuple[list[Node], list[system_message]]: text = utils.unescape(text) has_explicit_title, title, part = split_explicit_title(text) full_url = base_url % part @@ -111,7 +111,7 @@ def setup_link_roles(app: Sphinx) -> None: app.add_role(name, make_link_role(name, base_url, caption)) -def setup(app: Sphinx) -> Dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_config_value('extlinks', {}, 'env') app.add_config_value('extlinks_detect_hardcoded_links', False, 'env') diff --git a/sphinx/ext/githubpages.py b/sphinx/ext/githubpages.py index beef214ed..1e0cdc968 100644 --- a/sphinx/ext/githubpages.py +++ b/sphinx/ext/githubpages.py @@ -4,7 +4,7 @@ from __future__ import annotations import os import urllib -from typing import Any, Dict +from typing import Any import sphinx from sphinx.application import Sphinx @@ -26,6 +26,6 @@ def create_nojekyll_and_cname(app: Sphinx, env: BuildEnvironment) -> None: f.write(domain) -def setup(app: Sphinx) -> Dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.connect('env-updated', create_nojekyll_and_cname) return {'version': sphinx.__display_version__, 'parallel_read_safe': True} diff --git a/sphinx/ext/graphviz.py b/sphinx/ext/graphviz.py index 344c108b4..8e7e5828c 100644 --- a/sphinx/ext/graphviz.py +++ b/sphinx/ext/graphviz.py @@ -8,7 +8,7 @@ import re import subprocess from os import path from subprocess import CalledProcessError -from typing import Any, Dict, List, Optional, Tuple +from typing import Any, Optional from docutils import nodes from docutils.nodes import Node @@ -47,7 +47,7 @@ class ClickableMapDefinition: self.id: Optional[str] = None self.filename = filename self.content = content.splitlines() - self.clickable: List[str] = [] + self.clickable: list[str] = [] self.parse(dot=dot) @@ -118,7 +118,7 @@ class Graphviz(SphinxDirective): 'class': directives.class_option, } - def run(self) -> List[Node]: + def run(self) -> list[Node]: if self.arguments: document = self.state.document if self.content: @@ -186,7 +186,7 @@ class GraphvizSimple(SphinxDirective): 'class': directives.class_option, } - def run(self) -> List[Node]: + def run(self) -> list[Node]: node = graphviz() node['code'] = '%s %s {\n%s\n}\n' % \ (self.name, self.arguments[0], '\n'.join(self.content)) @@ -211,9 +211,9 @@ class GraphvizSimple(SphinxDirective): return [figure] -def render_dot(self: SphinxTranslator, code: str, options: Dict, format: str, +def render_dot(self: SphinxTranslator, code: str, options: dict, format: str, prefix: str = 'graphviz', filename: Optional[str] = None - ) -> Tuple[Optional[str], Optional[str]]: + ) -> tuple[Optional[str], Optional[str]]: """Render graphviz code into a PNG or PDF output file.""" graphviz_dot = options.get('graphviz_dot', self.builder.config.graphviz_dot) hashkey = (code + str(options) + str(graphviz_dot) + @@ -264,10 +264,10 @@ def render_dot(self: SphinxTranslator, code: str, options: Dict, format: str, '[stdout]\n%r') % (exc.stderr, exc.stdout)) from exc -def render_dot_html(self: HTML5Translator, node: graphviz, code: str, options: Dict, +def render_dot_html(self: HTML5Translator, node: graphviz, code: str, options: dict, prefix: str = 'graphviz', imgcls: Optional[str] = None, alt: Optional[str] = None, filename: Optional[str] = None - ) -> Tuple[str, str]: + ) -> tuple[str, str]: format = self.builder.config.graphviz_output_format try: if format not in ('png', 'svg'): @@ -322,7 +322,7 @@ def html_visit_graphviz(self: HTML5Translator, node: graphviz) -> None: def render_dot_latex(self: LaTeXTranslator, node: graphviz, code: str, - options: Dict, prefix: str = 'graphviz', filename: Optional[str] = None + options: dict, prefix: str = 'graphviz', filename: Optional[str] = None ) -> None: try: fname, outfn = render_dot(self, code, options, 'pdf', prefix, filename) @@ -360,7 +360,7 @@ def latex_visit_graphviz(self: LaTeXTranslator, node: graphviz) -> None: def render_dot_texinfo(self: TexinfoTranslator, node: graphviz, code: str, - options: Dict, prefix: str = 'graphviz') -> None: + options: dict, prefix: str = 'graphviz') -> None: try: fname, outfn = render_dot(self, code, options, 'png', prefix) except GraphvizError as exc: @@ -398,7 +398,7 @@ def on_build_finished(app: Sphinx, exc: Exception) -> None: copy_asset(src, dst) -def setup(app: Sphinx) -> Dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_node(graphviz, html=(html_visit_graphviz, None), latex=(latex_visit_graphviz, None), diff --git a/sphinx/ext/ifconfig.py b/sphinx/ext/ifconfig.py index b9339ee2d..f843dbd98 100644 --- a/sphinx/ext/ifconfig.py +++ b/sphinx/ext/ifconfig.py @@ -16,7 +16,7 @@ namespace of the project configuration (that is, all variables from from __future__ import annotations -from typing import Any, Dict, List +from typing import Any from docutils import nodes from docutils.nodes import Node @@ -40,7 +40,7 @@ class IfConfig(SphinxDirective): final_argument_whitespace = True option_spec: OptionSpec = {} - def run(self) -> List[Node]: + def run(self) -> list[Node]: node = ifconfig() node.document = self.state.document self.set_source_info(node) @@ -71,7 +71,7 @@ def process_ifconfig_nodes(app: Sphinx, doctree: nodes.document, docname: str) - node.replace_self(node.children) -def setup(app: Sphinx) -> Dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_node(ifconfig) app.add_directive('ifconfig', IfConfig) app.connect('doctree-resolved', process_ifconfig_nodes) diff --git a/sphinx/ext/imgconverter.py b/sphinx/ext/imgconverter.py index 710bd2fa0..ed2540cc3 100644 --- a/sphinx/ext/imgconverter.py +++ b/sphinx/ext/imgconverter.py @@ -5,7 +5,7 @@ from __future__ import annotations import subprocess import sys from subprocess import CalledProcessError -from typing import Any, Dict +from typing import Any import sphinx from sphinx.application import Sphinx @@ -71,7 +71,7 @@ class ImagemagickConverter(ImageConverter): (exc.stderr, exc.stdout)) from exc -def setup(app: Sphinx) -> Dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_post_transform(ImagemagickConverter) if sys.platform == 'win32': # On Windows, we use Imagemagik v7 by default to avoid the trouble for diff --git a/sphinx/ext/imgmath.py b/sphinx/ext/imgmath.py index 598353569..2af25788b 100644 --- a/sphinx/ext/imgmath.py +++ b/sphinx/ext/imgmath.py @@ -9,7 +9,7 @@ import subprocess import tempfile from os import path from subprocess import CalledProcessError -from typing import Any, Dict, List, Optional, Tuple +from typing import Any, Optional from docutils import nodes from docutils.nodes import Element @@ -144,7 +144,7 @@ def compile_math(latex: str, builder: Builder) -> str: raise MathExtError('latex exited with error', exc.stderr, exc.stdout) from exc -def convert_dvi_to_image(command: List[str], name: str) -> Tuple[str, str]: +def convert_dvi_to_image(command: list[str], name: str) -> tuple[str, str]: """Convert DVI file to specific image format.""" try: ret = subprocess.run(command, capture_output=True, check=True, encoding='ascii') @@ -205,7 +205,7 @@ def convert_dvi_to_svg(dvipath: str, builder: Builder, out_path: str) -> Optiona def render_math( self: HTML5Translator, math: str, -) -> Tuple[Optional[str], Optional[int]]: +) -> tuple[Optional[str], Optional[int]]: """Render the LaTeX math expression *math* using latex and dvipng or dvisvgm. @@ -366,7 +366,7 @@ def html_visit_displaymath(self: HTML5Translator, node: nodes.math_block) -> Non raise nodes.SkipNode -def setup(app: Sphinx) -> Dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_html_math_renderer('imgmath', (html_visit_math, None), (html_visit_displaymath, None)) diff --git a/sphinx/ext/inheritance_diagram.py b/sphinx/ext/inheritance_diagram.py index f848ac037..b83cc437f 100644 --- a/sphinx/ext/inheritance_diagram.py +++ b/sphinx/ext/inheritance_diagram.py @@ -34,7 +34,7 @@ import builtins import inspect import re from importlib import import_module -from typing import Any, Dict, Iterable, List, Optional, Tuple, cast +from typing import Any, Iterable, Optional, cast from docutils import nodes from docutils.nodes import Node @@ -132,9 +132,9 @@ class InheritanceGraph: from all the way to the root "object", and then is able to generate a graphviz dot graph from them. """ - def __init__(self, class_names: List[str], currmodule: str, show_builtins: bool = False, + def __init__(self, class_names: list[str], currmodule: str, show_builtins: bool = False, private_bases: bool = False, parts: int = 0, - aliases: Optional[Dict[str, str]] = None, top_classes: List[Any] = [] + aliases: Optional[dict[str, str]] = None, top_classes: list[Any] = [] ) -> None: """*class_names* is a list of child classes to show bases from. @@ -149,16 +149,16 @@ class InheritanceGraph: raise InheritanceException('No classes found for ' 'inheritance diagram') - def _import_classes(self, class_names: List[str], currmodule: str) -> List[Any]: + def _import_classes(self, class_names: list[str], currmodule: str) -> list[Any]: """Import a list of classes.""" - classes: List[Any] = [] + classes: list[Any] = [] for name in class_names: classes.extend(import_classes(name, currmodule)) return classes - def _class_info(self, classes: List[Any], show_builtins: bool, private_bases: bool, - parts: int, aliases: Dict[str, str], top_classes: List[Any] - ) -> List[Tuple[str, str, List[str], str]]: + def _class_info(self, classes: list[Any], show_builtins: bool, private_bases: bool, + parts: int, aliases: dict[str, str], top_classes: list[Any] + ) -> list[tuple[str, str, list[str], str]]: """Return name and bases for all classes that are ancestors of *classes*. @@ -195,7 +195,7 @@ class InheritanceGraph: except Exception: # might raise AttributeError for strange classes pass - baselist: List[str] = [] + baselist: list[str] = [] all_classes[cls] = (nodename, fullname, baselist, tooltip) if fullname in top_classes: @@ -216,7 +216,7 @@ class InheritanceGraph: return list(all_classes.values()) def class_name( - self, cls: Any, parts: int = 0, aliases: Optional[Dict[str, str]] = None + self, cls: Any, parts: int = 0, aliases: Optional[dict[str, str]] = None ) -> str: """Given a class object, return a fully-qualified name. @@ -237,7 +237,7 @@ class InheritanceGraph: return aliases[result] return result - def get_all_class_names(self) -> List[str]: + def get_all_class_names(self) -> list[str]: """Get all of the class names involved in the graph.""" return [fullname for (_, fullname, _, _) in self.class_info] @@ -261,15 +261,15 @@ class InheritanceGraph: 'style': '"setlinewidth(0.5)"', } - def _format_node_attrs(self, attrs: Dict[str, Any]) -> str: + def _format_node_attrs(self, attrs: dict[str, Any]) -> str: return ','.join(['%s=%s' % x for x in sorted(attrs.items())]) - def _format_graph_attrs(self, attrs: Dict[str, Any]) -> str: + def _format_graph_attrs(self, attrs: dict[str, Any]) -> str: return ''.join(['%s=%s;\n' % x for x in sorted(attrs.items())]) - def generate_dot(self, name: str, urls: Dict[str, str] = {}, + def generate_dot(self, name: str, urls: dict[str, str] = {}, env: Optional[BuildEnvironment] = None, - graph_attrs: Dict = {}, node_attrs: Dict = {}, edge_attrs: Dict = {} + graph_attrs: dict = {}, node_attrs: dict = {}, edge_attrs: dict = {} ) -> str: """Generate a graphviz dot graph from the classes that were passed in to __init__. @@ -292,7 +292,7 @@ class InheritanceGraph: n_attrs.update(env.config.inheritance_node_attrs) e_attrs.update(env.config.inheritance_edge_attrs) - res: List[str] = [] + res: list[str] = [] res.append('digraph %s {\n' % name) res.append(self._format_graph_attrs(g_attrs)) @@ -338,7 +338,7 @@ class InheritanceDiagram(SphinxDirective): 'top-classes': directives.unchanged_required, } - def run(self) -> List[Node]: + def run(self) -> list[Node]: node = inheritance_diagram() node.document = self.state.document class_names = self.arguments[0].split() @@ -457,7 +457,7 @@ def skip(self: nodes.NodeVisitor, node: inheritance_diagram) -> None: raise nodes.SkipNode -def setup(app: Sphinx) -> Dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.setup_extension('sphinx.ext.graphviz') app.add_node( inheritance_diagram, diff --git a/sphinx/ext/intersphinx.py b/sphinx/ext/intersphinx.py index 6d814a9a4..cd29bbdc5 100644 --- a/sphinx/ext/intersphinx.py +++ b/sphinx/ext/intersphinx.py @@ -26,7 +26,7 @@ import sys import time from os import path from types import ModuleType -from typing import IO, Any, Dict, List, Optional, Tuple, cast +from typing import IO, Any, Optional, cast from urllib.parse import urlsplit, urlunsplit from docutils import nodes @@ -63,7 +63,7 @@ class InventoryAdapter: self.env.intersphinx_named_inventory = {} # type: ignore @property - def cache(self) -> Dict[str, Tuple[str, int, Inventory]]: + def cache(self) -> dict[str, tuple[str, int, Inventory]]: return self.env.intersphinx_cache # type: ignore @property @@ -71,7 +71,7 @@ class InventoryAdapter: return self.env.intersphinx_inventory # type: ignore @property - def named_inventory(self) -> Dict[str, Inventory]: + def named_inventory(self) -> dict[str, Inventory]: return self.env.intersphinx_named_inventory # type: ignore def clear(self) -> None: @@ -291,7 +291,7 @@ def _create_element_from_result(domain: Domain, inv_name: Optional[str], def _resolve_reference_in_domain_by_target( inv_name: Optional[str], inventory: Inventory, - domain: Domain, objtypes: List[str], + domain: Domain, objtypes: list[str], target: str, node: pending_xref, contnode: TextElement) -> Optional[Element]: for objtype in objtypes: @@ -324,7 +324,7 @@ def _resolve_reference_in_domain_by_target( def _resolve_reference_in_domain(env: BuildEnvironment, inv_name: Optional[str], inventory: Inventory, honor_disabled_refs: bool, - domain: Domain, objtypes: List[str], + domain: Domain, objtypes: list[str], node: pending_xref, contnode: TextElement ) -> Optional[Element]: # we adjust the object types for backwards compatibility @@ -473,7 +473,7 @@ class IntersphinxDispatcher(CustomReSTDispatcher): """ def role(self, role_name: str, language_module: ModuleType, lineno: int, reporter: Reporter - ) -> Tuple[RoleFunction, List[system_message]]: + ) -> tuple[RoleFunction, list[system_message]]: if len(role_name) > 9 and role_name.startswith(('external:', 'external+')): return IntersphinxRole(role_name), [] else: @@ -489,7 +489,7 @@ class IntersphinxRole(SphinxRole): def __init__(self, orig_name: str) -> None: self.orig_name = orig_name - def run(self) -> Tuple[List[Node], List[system_message]]: + def run(self) -> tuple[list[Node], list[system_message]]: assert self.name == self.orig_name.lower() inventory, name_suffix = self.get_inventory_and_name_suffix(self.orig_name) if inventory and not inventory_exists(self.env, inventory): @@ -511,7 +511,7 @@ class IntersphinxRole(SphinxRole): return result, messages - def get_inventory_and_name_suffix(self, name: str) -> Tuple[Optional[str], str]: + def get_inventory_and_name_suffix(self, name: str) -> tuple[Optional[str], str]: assert name.startswith('external'), name assert name[8] in ':+', name # either we have an explicit inventory name, i.e, @@ -523,7 +523,7 @@ class IntersphinxRole(SphinxRole): inv, suffix = IntersphinxRole._re_inv_ref.fullmatch(name, 8).group(2, 3) return inv, suffix - def get_role_name(self, name: str) -> Optional[Tuple[str, str]]: + def get_role_name(self, name: str) -> Optional[tuple[str, str]]: names = name.split(':') if len(names) == 1: # role @@ -554,7 +554,7 @@ class IntersphinxRole(SphinxRole): except ExtensionError: return False - def invoke_role(self, role: Tuple[str, str]) -> Tuple[List[Node], List[system_message]]: + def invoke_role(self, role: tuple[str, str]) -> tuple[list[Node], list[system_message]]: domain = self.env.get_domain(role[0]) if domain: role_func = domain.role(role[1]) @@ -594,7 +594,7 @@ class IntersphinxRoleResolver(ReferencesResolver): node.replace_self(newnode) -def install_dispatcher(app: Sphinx, docname: str, source: List[str]) -> None: +def install_dispatcher(app: Sphinx, docname: str, source: list[str]) -> None: """Enable IntersphinxDispatcher. .. note:: The installed dispatcher will be uninstalled on disabling sphinx_domain @@ -628,7 +628,7 @@ def normalize_intersphinx_mapping(app: Sphinx, config: Config) -> None: config.intersphinx_mapping.pop(key) -def setup(app: Sphinx) -> Dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_config_value('intersphinx_mapping', {}, True) app.add_config_value('intersphinx_cache_limit', 5, False) app.add_config_value('intersphinx_timeout', None, False) @@ -645,7 +645,7 @@ def setup(app: Sphinx) -> Dict[str, Any]: } -def inspect_main(argv: List[str]) -> None: +def inspect_main(argv: list[str]) -> None: """Debug functionality to print out an inventory""" if len(argv) < 1: print("Print out an inventory file.\n" diff --git a/sphinx/ext/linkcode.py b/sphinx/ext/linkcode.py index 9a2294e59..5cee2f05a 100644 --- a/sphinx/ext/linkcode.py +++ b/sphinx/ext/linkcode.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Any, Dict, Set +from typing import Any from docutils import nodes from docutils.nodes import Node @@ -35,7 +35,7 @@ def doctree_read(app: Sphinx, doctree: Node) -> None: for objnode in list(doctree.findall(addnodes.desc)): domain = objnode.get('domain') - uris: Set[str] = set() + uris: set[str] = set() for signode in objnode: if not isinstance(signode, addnodes.desc_signature): continue @@ -67,7 +67,7 @@ def doctree_read(app: Sphinx, doctree: Node) -> None: signode += onlynode -def setup(app: Sphinx) -> Dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.connect('doctree-read', doctree_read) app.add_config_value('linkcode_resolve', None, '') return {'version': sphinx.__display_version__, 'parallel_read_safe': True} diff --git a/sphinx/ext/mathjax.py b/sphinx/ext/mathjax.py index a69ee7f84..e33daecac 100644 --- a/sphinx/ext/mathjax.py +++ b/sphinx/ext/mathjax.py @@ -8,7 +8,7 @@ This requires the MathJax JavaScript library on your webserver/computer. from __future__ import annotations import json -from typing import Any, Dict, cast +from typing import Any, cast from docutils import nodes @@ -67,7 +67,7 @@ def html_visit_displaymath(self: HTML5Translator, node: nodes.math_block) -> Non raise nodes.SkipNode -def install_mathjax(app: Sphinx, pagename: str, templatename: str, context: Dict[str, Any], +def install_mathjax(app: Sphinx, pagename: str, templatename: str, context: dict[str, Any], event_arg: Any) -> None: if ( app.builder.format != 'html' or @@ -105,7 +105,7 @@ def install_mathjax(app: Sphinx, pagename: str, templatename: str, context: Dict app.add_js_file(app.config.mathjax_path, **options) -def setup(app: Sphinx) -> Dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_html_math_renderer('mathjax', (html_visit_math, None), (html_visit_displaymath, None)) diff --git a/sphinx/ext/napoleon/__init__.py b/sphinx/ext/napoleon/__init__.py index 53c731a2d..acdab8a10 100644 --- a/sphinx/ext/napoleon/__init__.py +++ b/sphinx/ext/napoleon/__init__.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Any, Dict, List +from typing import Any import sphinx from sphinx.application import Sphinx @@ -288,7 +288,7 @@ class Config: setattr(self, name, value) -def setup(app: Sphinx) -> Dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: """Sphinx extension setup function. When the extension is loaded, Sphinx imports this module and executes @@ -340,7 +340,7 @@ def _patch_python_domain() -> None: def _process_docstring(app: Sphinx, what: str, name: str, obj: Any, - options: Any, lines: List[str]) -> None: + options: Any, lines: list[str]) -> None: """Process the docstring for a given python object. Called when autodoc has read and processed a docstring. `lines` is a list diff --git a/sphinx/ext/napoleon/docstring.py b/sphinx/ext/napoleon/docstring.py index 1b19104f1..88a62de68 100644 --- a/sphinx/ext/napoleon/docstring.py +++ b/sphinx/ext/napoleon/docstring.py @@ -6,7 +6,7 @@ import collections import inspect import re from functools import partial -from typing import Any, Callable, Dict, List, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union from sphinx.application import Sphinx from sphinx.config import Config as SphinxConfig @@ -68,7 +68,7 @@ class Deque(collections.deque): raise StopIteration -def _convert_type_spec(_type: str, translations: Dict[str, str] = {}) -> str: +def _convert_type_spec(_type: str, translations: dict[str, str] = {}) -> str: """Convert type specification to reference in reST.""" if _type in translations: return translations[_type] @@ -149,7 +149,7 @@ class GoogleDocstring: def __init__( self, - docstring: Union[str, List[str]], + docstring: Union[str, list[str]], config: Optional[SphinxConfig] = None, app: Optional[Sphinx] = None, what: str = '', @@ -183,13 +183,13 @@ class GoogleDocstring: else: lines = docstring self._lines = Deque(map(str.rstrip, lines)) - self._parsed_lines: List[str] = [] + self._parsed_lines: list[str] = [] self._is_in_section = False self._section_indent = 0 if not hasattr(self, '_directive_sections'): - self._directive_sections: List[str] = [] + self._directive_sections: list[str] = [] if not hasattr(self, '_sections'): - self._sections: Dict[str, Callable] = { + self._sections: dict[str, Callable] = { 'args': self._parse_parameters_section, 'arguments': self._parse_parameters_section, 'attention': partial(self._parse_admonition, 'attention'), @@ -241,7 +241,7 @@ class GoogleDocstring: """ return '\n'.join(self.lines()) - def lines(self) -> List[str]: + def lines(self) -> list[str]: """Return the parsed lines of the docstring in reStructuredText format. Returns @@ -252,7 +252,7 @@ class GoogleDocstring: """ return self._parsed_lines - def _consume_indented_block(self, indent: int = 1) -> List[str]: + def _consume_indented_block(self, indent: int = 1) -> list[str]: lines = [] line = self._lines.get(0) while ( @@ -263,7 +263,7 @@ class GoogleDocstring: line = self._lines.get(0) return lines - def _consume_contiguous(self) -> List[str]: + def _consume_contiguous(self) -> list[str]: lines = [] while (self._lines and self._lines.get(0) and @@ -271,7 +271,7 @@ class GoogleDocstring: lines.append(self._lines.next()) return lines - def _consume_empty(self) -> List[str]: + def _consume_empty(self) -> list[str]: lines = [] line = self._lines.get(0) while self._lines and not line: @@ -280,7 +280,7 @@ class GoogleDocstring: return lines def _consume_field(self, parse_type: bool = True, prefer_type: bool = False - ) -> Tuple[str, str, List[str]]: + ) -> tuple[str, str, list[str]]: line = self._lines.next() before, colon, after = self._partition_field_on_colon(line) @@ -306,7 +306,7 @@ class GoogleDocstring: return _name, _type, _descs def _consume_fields(self, parse_type: bool = True, prefer_type: bool = False, - multiple: bool = False) -> List[Tuple[str, str, List[str]]]: + multiple: bool = False) -> list[tuple[str, str, list[str]]]: self._consume_empty() fields = [] while not self._is_section_break(): @@ -318,7 +318,7 @@ class GoogleDocstring: fields.append((_name, _type, _desc,)) return fields - def _consume_inline_attribute(self) -> Tuple[str, List[str]]: + def _consume_inline_attribute(self) -> tuple[str, list[str]]: line = self._lines.next() _type, colon, _desc = self._partition_field_on_colon(line) if not colon or not _desc: @@ -329,7 +329,7 @@ class GoogleDocstring: return _type, _descs def _consume_returns_section(self, preprocess_types: bool = False - ) -> List[Tuple[str, str, List[str]]]: + ) -> list[tuple[str, str, list[str]]]: lines = self._dedent(self._consume_to_next_section()) if lines: before, colon, after = self._partition_field_on_colon(lines[0]) @@ -352,7 +352,7 @@ class GoogleDocstring: else: return [] - def _consume_usage_section(self) -> List[str]: + def _consume_usage_section(self) -> list[str]: lines = self._dedent(self._consume_to_next_section()) return lines @@ -363,20 +363,20 @@ class GoogleDocstring: section = stripped_section return section - def _consume_to_end(self) -> List[str]: + def _consume_to_end(self) -> list[str]: lines = [] while self._lines: lines.append(self._lines.next()) return lines - def _consume_to_next_section(self) -> List[str]: + def _consume_to_next_section(self) -> list[str]: self._consume_empty() lines = [] while not self._is_section_break(): lines.append(self._lines.next()) return lines + self._consume_empty() - def _dedent(self, lines: List[str], full: bool = False) -> List[str]: + def _dedent(self, lines: list[str], full: bool = False) -> list[str]: if full: return [line.lstrip() for line in lines] else: @@ -394,7 +394,7 @@ class GoogleDocstring: else: return name - def _fix_field_desc(self, desc: List[str]) -> List[str]: + def _fix_field_desc(self, desc: list[str]) -> list[str]: if self._is_list(desc): desc = [''] + desc elif desc[0].endswith('::'): @@ -407,7 +407,7 @@ class GoogleDocstring: desc = ['', desc[0]] + self._indent(desc_block, 4) return desc - def _format_admonition(self, admonition: str, lines: List[str]) -> List[str]: + def _format_admonition(self, admonition: str, lines: list[str]) -> list[str]: lines = self._strip_empty(lines) if len(lines) == 1: return ['.. %s:: %s' % (admonition, lines[0].strip()), ''] @@ -418,8 +418,8 @@ class GoogleDocstring: return ['.. %s::' % admonition, ''] def _format_block( - self, prefix: str, lines: List[str], padding: Optional[str] = None - ) -> List[str]: + self, prefix: str, lines: list[str], padding: Optional[str] = None + ) -> list[str]: if lines: if padding is None: padding = ' ' * len(prefix) @@ -435,9 +435,9 @@ class GoogleDocstring: else: return [prefix] - def _format_docutils_params(self, fields: List[Tuple[str, str, List[str]]], + def _format_docutils_params(self, fields: list[tuple[str, str, list[str]]], field_role: str = 'param', type_role: str = 'type' - ) -> List[str]: + ) -> list[str]: lines = [] for _name, _type, _desc in fields: _desc = self._strip_empty(_desc) @@ -452,7 +452,7 @@ class GoogleDocstring: lines.append(':%s %s: %s' % (type_role, _name, _type)) return lines + [''] - def _format_field(self, _name: str, _type: str, _desc: List[str]) -> List[str]: + def _format_field(self, _name: str, _type: str, _desc: list[str]) -> list[str]: _desc = self._strip_empty(_desc) has_desc = any(_desc) separator = ' -- ' if has_desc else '' @@ -481,12 +481,12 @@ class GoogleDocstring: else: return [field] - def _format_fields(self, field_type: str, fields: List[Tuple[str, str, List[str]]] - ) -> List[str]: + def _format_fields(self, field_type: str, fields: list[tuple[str, str, list[str]]] + ) -> list[str]: field_type = ':%s:' % field_type.strip() padding = ' ' * len(field_type) multi = len(fields) > 1 - lines: List[str] = [] + lines: list[str] = [] for _name, _type, _desc in fields: field = self._format_field(_name, _type, _desc) if multi: @@ -515,13 +515,13 @@ class GoogleDocstring: return i return len(line) - def _get_initial_indent(self, lines: List[str]) -> int: + def _get_initial_indent(self, lines: list[str]) -> int: for line in lines: if line: return self._get_indent(line) return 0 - def _get_min_indent(self, lines: List[str]) -> int: + def _get_min_indent(self, lines: list[str]) -> int: min_indent = None for line in lines: if line: @@ -532,7 +532,7 @@ class GoogleDocstring: min_indent = indent return min_indent or 0 - def _indent(self, lines: List[str], n: int = 4) -> List[str]: + def _indent(self, lines: list[str], n: int = 4) -> list[str]: return [(' ' * n) + line for line in lines] def _is_indented(self, line: str, indent: int = 1) -> bool: @@ -543,7 +543,7 @@ class GoogleDocstring: return False return False - def _is_list(self, lines: List[str]) -> bool: + def _is_list(self, lines: list[str]) -> bool: if not lines: return False if _bullet_list_regex.match(lines[0]): @@ -608,7 +608,7 @@ class GoogleDocstring: self._parsed_lines = self._consume_empty() if self._name and self._what in ('attribute', 'data', 'property'): - res: List[str] = [] + res: list[str] = [] try: res = self._parse_attribute_docstring() except StopIteration: @@ -636,19 +636,19 @@ class GoogleDocstring: lines = self._consume_to_next_section() self._parsed_lines.extend(lines) - def _parse_admonition(self, admonition: str, section: str) -> List[str]: + def _parse_admonition(self, admonition: str, section: str) -> list[str]: # type (str, str) -> List[str] lines = self._consume_to_next_section() return self._format_admonition(admonition, lines) - def _parse_attribute_docstring(self) -> List[str]: + def _parse_attribute_docstring(self) -> list[str]: _type, _desc = self._consume_inline_attribute() lines = self._format_field('', '', _desc) if _type: lines.extend(['', ':type: %s' % _type]) return lines - def _parse_attributes_section(self, section: str) -> List[str]: + def _parse_attributes_section(self, section: str) -> list[str]: lines = [] for _name, _type, _desc in self._consume_fields(): if not _type: @@ -674,7 +674,7 @@ class GoogleDocstring: lines.append('') return lines - def _parse_examples_section(self, section: str) -> List[str]: + def _parse_examples_section(self, section: str) -> list[str]: labels = { 'example': _('Example'), 'examples': _('Examples'), @@ -683,25 +683,25 @@ class GoogleDocstring: label = labels.get(section.lower(), section) return self._parse_generic_section(label, use_admonition) - def _parse_custom_generic_section(self, section: str) -> List[str]: + def _parse_custom_generic_section(self, section: str) -> list[str]: # for now, no admonition for simple custom sections return self._parse_generic_section(section, False) - def _parse_custom_params_style_section(self, section: str) -> List[str]: + def _parse_custom_params_style_section(self, section: str) -> list[str]: return self._format_fields(section, self._consume_fields()) - def _parse_custom_returns_style_section(self, section: str) -> List[str]: + def _parse_custom_returns_style_section(self, section: str) -> list[str]: fields = self._consume_returns_section(preprocess_types=True) return self._format_fields(section, fields) - def _parse_usage_section(self, section: str) -> List[str]: + def _parse_usage_section(self, section: str) -> list[str]: header = ['.. rubric:: Usage:', ''] block = ['.. code-block:: python', ''] lines = self._consume_usage_section() lines = self._indent(lines, 3) return header + block + lines + [''] - def _parse_generic_section(self, section: str, use_admonition: bool) -> List[str]: + def _parse_generic_section(self, section: str, use_admonition: bool) -> list[str]: lines = self._strip_empty(self._consume_to_next_section()) lines = self._dedent(lines) if use_admonition: @@ -714,7 +714,7 @@ class GoogleDocstring: else: return [header, ''] - def _parse_keyword_arguments_section(self, section: str) -> List[str]: + def _parse_keyword_arguments_section(self, section: str) -> list[str]: fields = self._consume_fields() if self._config.napoleon_use_keyword: return self._format_docutils_params( @@ -724,8 +724,8 @@ class GoogleDocstring: else: return self._format_fields(_('Keyword Arguments'), fields) - def _parse_methods_section(self, section: str) -> List[str]: - lines: List[str] = [] + def _parse_methods_section(self, section: str) -> list[str]: + lines: list[str] = [] for _name, _type, _desc in self._consume_fields(parse_type=False): lines.append('.. method:: %s' % _name) if self._opt and 'noindex' in self._opt: @@ -735,11 +735,11 @@ class GoogleDocstring: lines.append('') return lines - def _parse_notes_section(self, section: str) -> List[str]: + def _parse_notes_section(self, section: str) -> list[str]: use_admonition = self._config.napoleon_use_admonition_for_notes return self._parse_generic_section(_('Notes'), use_admonition) - def _parse_other_parameters_section(self, section: str) -> List[str]: + def _parse_other_parameters_section(self, section: str) -> list[str]: if self._config.napoleon_use_param: # Allow to declare multiple parameters at once (ex: x, y: int) fields = self._consume_fields(multiple=True) @@ -748,7 +748,7 @@ class GoogleDocstring: fields = self._consume_fields() return self._format_fields(_('Other Parameters'), fields) - def _parse_parameters_section(self, section: str) -> List[str]: + def _parse_parameters_section(self, section: str) -> list[str]: if self._config.napoleon_use_param: # Allow to declare multiple parameters at once (ex: x, y: int) fields = self._consume_fields(multiple=True) @@ -757,9 +757,9 @@ class GoogleDocstring: fields = self._consume_fields() return self._format_fields(_('Parameters'), fields) - def _parse_raises_section(self, section: str) -> List[str]: + def _parse_raises_section(self, section: str) -> list[str]: fields = self._consume_fields(parse_type=False, prefer_type=True) - lines: List[str] = [] + lines: list[str] = [] for _name, _type, _desc in fields: m = self._name_rgx.match(_type) if m and m.group('name'): @@ -775,7 +775,7 @@ class GoogleDocstring: lines.append('') return lines - def _parse_receives_section(self, section: str) -> List[str]: + def _parse_receives_section(self, section: str) -> list[str]: if self._config.napoleon_use_param: # Allow to declare multiple parameters at once (ex: x, y: int) fields = self._consume_fields(multiple=True) @@ -784,15 +784,15 @@ class GoogleDocstring: fields = self._consume_fields() return self._format_fields(_('Receives'), fields) - def _parse_references_section(self, section: str) -> List[str]: + def _parse_references_section(self, section: str) -> list[str]: use_admonition = self._config.napoleon_use_admonition_for_references return self._parse_generic_section(_('References'), use_admonition) - def _parse_returns_section(self, section: str) -> List[str]: + def _parse_returns_section(self, section: str) -> list[str]: fields = self._consume_returns_section() multi = len(fields) > 1 use_rtype = False if multi else self._config.napoleon_use_rtype - lines: List[str] = [] + lines: list[str] = [] for _name, _type, _desc in fields: if use_rtype: @@ -814,17 +814,17 @@ class GoogleDocstring: lines.append('') return lines - def _parse_see_also_section(self, section: str) -> List[str]: + def _parse_see_also_section(self, section: str) -> list[str]: return self._parse_admonition('seealso', section) - def _parse_warns_section(self, section: str) -> List[str]: + def _parse_warns_section(self, section: str) -> list[str]: return self._format_fields(_('Warns'), self._consume_fields()) - def _parse_yields_section(self, section: str) -> List[str]: + def _parse_yields_section(self, section: str) -> list[str]: fields = self._consume_returns_section(preprocess_types=True) return self._format_fields(_('Yields'), fields) - def _partition_field_on_colon(self, line: str) -> Tuple[str, str, str]: + def _partition_field_on_colon(self, line: str) -> tuple[str, str, str]: before_colon = [] after_colon = [] colon = '' @@ -846,7 +846,7 @@ class GoogleDocstring: colon, "".join(after_colon).strip()) - def _strip_empty(self, lines: List[str]) -> List[str]: + def _strip_empty(self, lines: list[str]) -> list[str]: if lines: start = -1 for i, line in enumerate(lines): @@ -881,7 +881,7 @@ class GoogleDocstring: return "" -def _recombine_set_tokens(tokens: List[str]) -> List[str]: +def _recombine_set_tokens(tokens: list[str]) -> list[str]: token_queue = collections.deque(tokens) keywords = ("optional", "default") @@ -937,7 +937,7 @@ def _recombine_set_tokens(tokens: List[str]) -> List[str]: return list(combine_set(token_queue)) -def _tokenize_type_spec(spec: str) -> List[str]: +def _tokenize_type_spec(spec: str) -> list[str]: def postprocess(item): if _default_regex.match(item): default = item[:7] @@ -1150,7 +1150,7 @@ class NumpyDocstring(GoogleDocstring): """ def __init__( self, - docstring: Union[str, List[str]], + docstring: Union[str, list[str]], config: Optional[SphinxConfig] = None, app: Optional[Sphinx] = None, what: str = '', @@ -1184,7 +1184,7 @@ class NumpyDocstring(GoogleDocstring): return func(name) def _consume_field(self, parse_type: bool = True, prefer_type: bool = False - ) -> Tuple[str, str, List[str]]: + ) -> tuple[str, str, list[str]]: line = self._lines.next() if parse_type: _name, _, _type = self._partition_field_on_colon(line) @@ -1212,7 +1212,7 @@ class NumpyDocstring(GoogleDocstring): return _name, _type, _desc def _consume_returns_section(self, preprocess_types: bool = False - ) -> List[Tuple[str, str, List[str]]]: + ) -> list[tuple[str, str, list[str]]]: return self._consume_fields(prefer_type=True) def _consume_section_header(self) -> str: @@ -1243,14 +1243,14 @@ class NumpyDocstring(GoogleDocstring): return True return False - def _parse_see_also_section(self, section: str) -> List[str]: + def _parse_see_also_section(self, section: str) -> list[str]: lines = self._consume_to_next_section() try: return self._parse_numpydoc_see_also_section(lines) except ValueError: return self._format_admonition('seealso', lines) - def _parse_numpydoc_see_also_section(self, content: List[str]) -> List[str]: + def _parse_numpydoc_see_also_section(self, content: list[str]) -> list[str]: """ Derived from the NumpyDoc implementation of _parse_see_also. @@ -1264,7 +1264,7 @@ class NumpyDocstring(GoogleDocstring): """ items = [] - def parse_item_name(text: str) -> Tuple[str, Optional[str]]: + def parse_item_name(text: str) -> tuple[str, Optional[str]]: """Match ':role:`name`' or 'name'""" m = self._name_rgx.match(text) if m: @@ -1275,7 +1275,7 @@ class NumpyDocstring(GoogleDocstring): return g[2], g[1] raise ValueError("%s is not a item name" % text) - def push_item(name: str, rest: List[str]) -> None: + def push_item(name: str, rest: list[str]) -> None: if not name: return None name, role = parse_item_name(name) @@ -1299,7 +1299,7 @@ class NumpyDocstring(GoogleDocstring): return new_func, description, role current_func = None - rest: List[str] = [] + rest: list[str] = [] for line in content: if not line.strip(): @@ -1334,7 +1334,7 @@ class NumpyDocstring(GoogleDocstring): for func, description, role in items ] - lines: List[str] = [] + lines: list[str] = [] last_had_desc = True for name, desc, role in items: if role: diff --git a/sphinx/ext/todo.py b/sphinx/ext/todo.py index 67409ddf9..a21f36ec1 100644 --- a/sphinx/ext/todo.py +++ b/sphinx/ext/todo.py @@ -7,7 +7,7 @@ with a backlink to the original location. from __future__ import annotations -from typing import Any, Dict, List, cast +from typing import Any, cast from docutils import nodes from docutils.nodes import Element, Node @@ -53,7 +53,7 @@ class Todo(BaseAdmonition, SphinxDirective): 'name': directives.unchanged, } - def run(self) -> List[Node]: + def run(self) -> list[Node]: if not self.options.get('class'): self.options['class'] = ['admonition-todo'] @@ -76,13 +76,13 @@ class TodoDomain(Domain): label = 'todo' @property - def todos(self) -> Dict[str, List[todo_node]]: + def todos(self) -> dict[str, list[todo_node]]: return self.data.setdefault('todos', {}) def clear_doc(self, docname: str) -> None: self.todos.pop(docname, None) - def merge_domaindata(self, docnames: List[str], otherdata: Dict) -> None: + def merge_domaindata(self, docnames: list[str], otherdata: dict) -> None: for docname in docnames: self.todos[docname] = otherdata['todos'][docname] @@ -109,7 +109,7 @@ class TodoList(SphinxDirective): final_argument_whitespace = False option_spec: OptionSpec = {} - def run(self) -> List[Node]: + def run(self) -> list[Node]: # Simply insert an empty todolist node which will be replaced later # when process_todo_nodes is called return [todolist('')] @@ -126,14 +126,14 @@ class TodoListProcessor: self.process(doctree, docname) def process(self, doctree: nodes.document, docname: str) -> None: - todos: List[todo_node] = sum(self.domain.todos.values(), []) + todos: list[todo_node] = sum(self.domain.todos.values(), []) for node in list(doctree.findall(todolist)): if not self.config.todo_include_todos: node.parent.remove(node) continue if node.get('ids'): - content: List[Element] = [nodes.target()] + content: list[Element] = [nodes.target()] else: content = [] @@ -218,7 +218,7 @@ def latex_depart_todo_node(self: LaTeXTranslator, node: todo_node) -> None: self.body.append('\\end{sphinxadmonition}\n') -def setup(app: Sphinx) -> Dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_event('todo-defined') app.add_config_value('todo_include_todos', False, 'html') app.add_config_value('todo_link_only', False, 'html') diff --git a/sphinx/ext/viewcode.py b/sphinx/ext/viewcode.py index 9a62ce348..6a9845722 100644 --- a/sphinx/ext/viewcode.py +++ b/sphinx/ext/viewcode.py @@ -5,7 +5,7 @@ from __future__ import annotations import posixpath import traceback from os import path -from typing import Any, Dict, Generator, Iterable, Optional, Set, Tuple, cast +from typing import Any, Generator, Iterable, Optional, cast from docutils import nodes from docutils.nodes import Element, Node @@ -103,7 +103,7 @@ def doctree_read(app: Sphinx, doctree: Node) -> None: for objnode in list(doctree.findall(addnodes.desc)): if objnode.get('domain') != 'py': continue - names: Set[str] = set() + names: set[str] = set() for signode in objnode: if not isinstance(signode, addnodes.desc_signature): continue @@ -221,7 +221,7 @@ def should_generate_module_page(app: Sphinx, modname: str) -> bool: return True -def collect_pages(app: Sphinx) -> Generator[Tuple[str, Dict[str, Any], str], None, None]: +def collect_pages(app: Sphinx) -> Generator[tuple[str, dict[str, Any], str], None, None]: env = app.builder.env if not hasattr(env, '_viewcode_modules'): return @@ -321,7 +321,7 @@ def collect_pages(app: Sphinx) -> Generator[Tuple[str, Dict[str, Any], str], Non yield (posixpath.join(OUTPUT_DIRNAME, 'index'), context, 'page.html') -def setup(app: Sphinx) -> Dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_config_value('viewcode_import', None, False) app.add_config_value('viewcode_enable_epub', False, False) app.add_config_value('viewcode_follow_imported_members', True, False) |
