summaryrefslogtreecommitdiff
path: root/sphinx/ext
diff options
context:
space:
mode:
authorAdam Turner <9087854+aa-turner@users.noreply.github.com>2022-12-30 21:13:29 +0000
committerAdam Turner <9087854+aa-turner@users.noreply.github.com>2023-01-01 20:48:38 +0000
commit26f79b0d2dd88b353ac65623897bdfbe8bc07cab (patch)
tree0d2f0c752cf1f49a45cde1d7f414d75a6114f1ce /sphinx/ext
parentf4c8a0a68e0013808d169357c9f77ebdf19d0f4e (diff)
downloadsphinx-git-26f79b0d2dd88b353ac65623897bdfbe8bc07cab.tar.gz
Use PEP 595 types
Diffstat (limited to 'sphinx/ext')
-rw-r--r--sphinx/ext/apidoc.py32
-rw-r--r--sphinx/ext/autodoc/__init__.py108
-rw-r--r--sphinx/ext/autodoc/directive.py10
-rw-r--r--sphinx/ext/autodoc/importer.py16
-rw-r--r--sphinx/ext/autodoc/mock.py18
-rw-r--r--sphinx/ext/autodoc/preserve_defaults.py6
-rw-r--r--sphinx/ext/autodoc/type_comment.py6
-rw-r--r--sphinx/ext/autodoc/typehints.py16
-rw-r--r--sphinx/ext/autosectionlabel.py4
-rw-r--r--sphinx/ext/autosummary/__init__.py56
-rw-r--r--sphinx/ext/autosummary/generate.py54
-rw-r--r--sphinx/ext/coverage.py22
-rw-r--r--sphinx/ext/doctest.py29
-rw-r--r--sphinx/ext/duration.py10
-rw-r--r--sphinx/ext/extlinks.py8
-rw-r--r--sphinx/ext/githubpages.py4
-rw-r--r--sphinx/ext/graphviz.py22
-rw-r--r--sphinx/ext/ifconfig.py6
-rw-r--r--sphinx/ext/imgconverter.py4
-rw-r--r--sphinx/ext/imgmath.py8
-rw-r--r--sphinx/ext/inheritance_diagram.py36
-rw-r--r--sphinx/ext/intersphinx.py26
-rw-r--r--sphinx/ext/linkcode.py6
-rw-r--r--sphinx/ext/mathjax.py6
-rw-r--r--sphinx/ext/napoleon/__init__.py6
-rw-r--r--sphinx/ext/napoleon/docstring.py140
-rw-r--r--sphinx/ext/todo.py16
-rw-r--r--sphinx/ext/viewcode.py8
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)