diff options
author | Adam Turner <9087854+AA-Turner@users.noreply.github.com> | 2023-01-02 00:01:14 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-02 00:01:14 +0000 |
commit | 4032070e8131f518bbb8a04e8d63c5af4df9b59d (patch) | |
tree | 47b14f58d5337448e8358029264ebcd6d1ae7351 | |
parent | ede68fa423107fbab74d07b307d7dcb03c00dfbd (diff) | |
download | sphinx-git-4032070e8131f518bbb8a04e8d63c5af4df9b59d.tar.gz |
Run pyupgrade (#11070)
124 files changed, 818 insertions, 839 deletions
diff --git a/doc/development/tutorials/examples/recipe.py b/doc/development/tutorials/examples/recipe.py index 845628864..6bfd99900 100644 --- a/doc/development/tutorials/examples/recipe.py +++ b/doc/development/tutorials/examples/recipe.py @@ -117,7 +117,7 @@ class RecipeDomain(Domain): } def get_full_qualified_name(self, node): - return '{}.{}'.format('recipe', node.arguments[0]) + return f'recipe.{node.arguments[0]}' def get_objects(self): yield from self.data['recipes'] diff --git a/sphinx/addnodes.py b/sphinx/addnodes.py index 07807e46e..d5a92e656 100644 --- a/sphinx/addnodes.py +++ b/sphinx/addnodes.py @@ -514,7 +514,7 @@ class manpage(nodes.Inline, nodes.FixedTextElement): """Node for references to manpages.""" -def setup(app: "Sphinx") -> dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_node(toctree) app.add_node(desc) diff --git a/sphinx/application.py b/sphinx/application.py index 6e0ed0bf0..b3d7d2269 100644 --- a/sphinx/application.py +++ b/sphinx/application.py @@ -320,7 +320,7 @@ class Sphinx: def preload_builder(self, name: str) -> None: self.registry.preload_builder(self, name) - def create_builder(self, name: str) -> "Builder": + def create_builder(self, name: str) -> Builder: if name is None: logger.info(__('No builder selected, using default: html')) name = 'html' @@ -476,7 +476,7 @@ class Sphinx: # registering addon parts - def add_builder(self, builder: type["Builder"], override: bool = False) -> None: + def add_builder(self, builder: type[Builder], override: bool = False) -> None: """Register a new builder. :param builder: A builder class @@ -1309,7 +1309,7 @@ class TemplateBridge: def init( self, - builder: "Builder", + builder: Builder, theme: Theme | None = None, dirs: list[str] | None = None ) -> None: diff --git a/sphinx/builders/__init__.py b/sphinx/builders/__init__.py index b6d71eb9d..2bbd6ca9b 100644 --- a/sphinx/builders/__init__.py +++ b/sphinx/builders/__init__.py @@ -79,7 +79,7 @@ class Builder: #: The builder supports data URIs or not. supported_data_uri_images = False - def __init__(self, app: "Sphinx", env: BuildEnvironment = None) -> None: + def __init__(self, app: Sphinx, env: BuildEnvironment = None) -> None: self.srcdir = app.srcdir self.confdir = app.confdir self.outdir = app.outdir @@ -662,8 +662,8 @@ class Builder: # At the moment, only XXX_use_index is looked up this way. # Every new builder variant must be registered in Config.config_values. try: - optname = '%s_%s' % (self.name, option) + optname = f'{self.name}_{option}' return getattr(self.config, optname) except AttributeError: - optname = '%s_%s' % (default, option) + optname = f'{default}_{option}' return getattr(self.config, optname) diff --git a/sphinx/builders/changes.py b/sphinx/builders/changes.py index dd14cdc7c..b8869c7a0 100644 --- a/sphinx/builders/changes.py +++ b/sphinx/builders/changes.py @@ -63,26 +63,24 @@ class ChangesBuilder(Builder): context = changeset.content.replace('\n', ' ') if descname and changeset.docname.startswith('c-api'): if context: - entry = '<b>%s</b>: <i>%s:</i> %s' % (descname, ttext, - context) + entry = f'<b>{descname}</b>: <i>{ttext}:</i> {context}' else: - entry = '<b>%s</b>: <i>%s</i>.' % (descname, ttext) + entry = f'<b>{descname}</b>: <i>{ttext}</i>.' apichanges.append((entry, changeset.docname, changeset.lineno)) elif descname or changeset.module: module = changeset.module or _('Builtins') if not descname: descname = _('Module level') if context: - entry = '<b>%s</b>: <i>%s:</i> %s' % (descname, ttext, - context) + entry = f'<b>{descname}</b>: <i>{ttext}:</i> {context}' else: - entry = '<b>%s</b>: <i>%s</i>.' % (descname, ttext) + entry = f'<b>{descname}</b>: <i>{ttext}</i>.' libchanges.setdefault(module, []).append((entry, changeset.docname, changeset.lineno)) else: if not context: continue - entry = '<i>%s:</i> %s' % (ttext.capitalize(), context) + entry = f'<i>{ttext.capitalize()}:</i> {context}' title = self.env.titles[changeset.docname].astext() otherchanges.setdefault((changeset.docname, title), []).append( (entry, changeset.docname, changeset.lineno)) @@ -143,8 +141,8 @@ class ChangesBuilder(Builder): def hl(self, text: str, version: str) -> str: text = html.escape(text) for directive in ('versionchanged', 'versionadded', 'deprecated'): - text = text.replace('.. %s:: %s' % (directive, version), - '<b>.. %s:: %s</b>' % (directive, version)) + text = text.replace(f'.. {directive}:: {version}', + f'<b>.. {directive}:: {version}</b>') return text def finish(self) -> None: diff --git a/sphinx/builders/gettext.py b/sphinx/builders/gettext.py index b2efc0d35..c8316b45c 100644 --- a/sphinx/builders/gettext.py +++ b/sphinx/builders/gettext.py @@ -7,7 +7,7 @@ from collections import OrderedDict, defaultdict from datetime import datetime, timedelta, tzinfo from os import getenv, path, walk from time import time -from typing import Any, Generator, Iterable, Union +from typing import Any, Generator, Iterable from uuid import uuid4 from docutils import nodes @@ -47,7 +47,7 @@ class Catalog: # msgid -> file, line, uid self.metadata: dict[str, list[tuple[str, int, str]]] = OrderedDict() - def add(self, msg: str, origin: Union[Element, "MsgOrigin"]) -> None: + def add(self, msg: str, origin: Element | MsgOrigin) -> None: if not hasattr(origin, 'uid'): # Nodes that are replicated like todo don't have a uid, # however i18n is also unnecessary. @@ -250,7 +250,7 @@ class MessageCatalogBuilder(I18nBuilder): origin = MsgOrigin(template, line) self.catalogs['sphinx'].add(msg, origin) except Exception as exc: - raise ThemeError('%s: %r' % (template, exc)) from exc + raise ThemeError(f'{template}: {exc!r}') from exc def build( self, docnames: Iterable[str], summary: str | None = None, method: str = 'update' diff --git a/sphinx/builders/html/__init__.py b/sphinx/builders/html/__init__.py index d9f72298e..9c11e919a 100644 --- a/sphinx/builders/html/__init__.py +++ b/sphinx/builders/html/__init__.py @@ -103,7 +103,7 @@ class Stylesheet(str): priority: int = None def __new__(cls, filename: str, *args: str, priority: int = 500, **attributes: Any - ) -> "Stylesheet": + ) -> Stylesheet: self = str.__new__(cls, filename) self.filename = filename self.priority = priority @@ -128,7 +128,7 @@ class JavaScript(str): filename: str = None priority: int = None - def __new__(cls, filename: str, priority: int = 500, **attributes: str) -> "JavaScript": + def __new__(cls, filename: str, priority: int = 500, **attributes: str) -> JavaScript: self = str.__new__(cls, filename) self.filename = filename self.priority = priority @@ -145,7 +145,7 @@ class BuildInfo: """ @classmethod - def load(cls, f: IO) -> "BuildInfo": + def load(cls, f: IO) -> BuildInfo: try: lines = f.readlines() assert lines[0].rstrip() == '# Sphinx build info version 1' @@ -172,7 +172,7 @@ class BuildInfo: if tags: self.tags_hash = get_stable_hash(sorted(tags)) - def __eq__(self, other: "BuildInfo") -> bool: # type: ignore + def __eq__(self, other: BuildInfo) -> bool: # type: ignore return (self.config_hash == other.config_hash and self.tags_hash == other.tags_hash) @@ -489,7 +489,7 @@ class StandaloneHTMLBuilder(Builder): for domain_name in sorted(self.env.domains): domain: Domain = self.env.domains[domain_name] for indexcls in domain.indices: - indexname = '%s-%s' % (domain.name, indexcls.name) + indexname = f'{domain.name}-{indexcls.name}' if isinstance(indices_config, list): if indexname not in indices_config: continue @@ -1197,7 +1197,7 @@ def setup_css_tag_helper(app: Sphinx, pagename: str, templatename: str, for key in sorted(css.attributes): value = css.attributes[key] if value is not None: - attrs.append('%s="%s"' % (key, html.escape(value, True))) + attrs.append(f'{key}="{html.escape(value, True)}"') attrs.append('href="%s"' % pathto(css.filename, resource=True)) return '<link %s />' % ' '.join(attrs) @@ -1224,7 +1224,7 @@ def setup_js_tag_helper(app: Sphinx, pagename: str, templatename: str, elif key == 'data_url_root': attrs.append('data-url_root="%s"' % pathto('', resource=True)) else: - attrs.append('%s="%s"' % (key, html.escape(value, True))) + attrs.append(f'{key}="{html.escape(value, True)}"') if js.filename: attrs.append('src="%s"' % pathto(js.filename, resource=True)) else: @@ -1232,9 +1232,9 @@ def setup_js_tag_helper(app: Sphinx, pagename: str, templatename: str, attrs.append('src="%s"' % pathto(js, resource=True)) if attrs: - return '<script %s>%s</script>' % (' '.join(attrs), body) + return f'<script {" ".join(attrs)}>{body}</script>' else: - return '<script>%s</script>' % body + return f'<script>{body}</script>' context['js_tag'] = js_tag diff --git a/sphinx/builders/latex/__init__.py b/sphinx/builders/latex/__init__.py index b9d4d657c..92fc0c7b6 100644 --- a/sphinx/builders/latex/__init__.py +++ b/sphinx/builders/latex/__init__.py @@ -238,11 +238,11 @@ class LaTeXBuilder(Builder): self.context['classoptions'] += ',' + self.babel.get_language() options = self.babel.get_mainlanguage_options() if options: - language = r'\setmainlanguage[%s]{%s}' % (options, self.babel.get_language()) + language = fr'\setmainlanguage[{options}]{{{self.babel.get_language()}}}' else: language = r'\setmainlanguage{%s}' % self.babel.get_language() - self.context['multilingual'] = '%s\n%s' % (self.context['polyglossia'], language) + self.context['multilingual'] = f'{self.context["polyglossia"]}\n{language}' def write_stylesheet(self) -> None: highlighter = highlighting.PygmentsBridge('latex', self.config.pygments_style) diff --git a/sphinx/builders/linkcheck.py b/sphinx/builders/linkcheck.py index b2249308d..bdce45c68 100644 --- a/sphinx/builders/linkcheck.py +++ b/sphinx/builders/linkcheck.py @@ -177,7 +177,7 @@ class CheckExternalLinksBuilder(DummyBuilder): def write_entry(self, what: str, docname: str, filename: str, line: int, uri: str) -> None: - self.txt_outfile.write("%s:%s: [%s] %s\n" % (filename, line, what, uri)) + self.txt_outfile.write(f"{filename}:{line}: [{what}] {uri}\n") def write_linkstat(self, data: dict) -> None: self.json_outfile.write(json.dumps(data)) @@ -248,8 +248,8 @@ class HyperlinkAvailabilityChecker: class HyperlinkAvailabilityCheckWorker(Thread): """A worker class for checking the availability of hyperlinks.""" - def __init__(self, env: BuildEnvironment, config: Config, rqueue: 'Queue[CheckResult]', - wqueue: 'Queue[CheckRequest]', rate_limits: dict[str, RateLimit]) -> None: + def __init__(self, env: BuildEnvironment, config: Config, rqueue: Queue[CheckResult], + wqueue: Queue[CheckRequest], rate_limits: dict[str, RateLimit]) -> None: self.config = config self.env = env self.rate_limits = rate_limits @@ -272,8 +272,8 @@ class HyperlinkAvailabilityCheckWorker(Thread): def get_request_headers() -> dict[str, str]: url = urlparse(uri) - candidates = ["%s://%s" % (url.scheme, url.netloc), - "%s://%s/" % (url.scheme, url.netloc), + candidates = [f"{url.scheme}://{url.netloc}", + f"{url.scheme}://{url.netloc}/", uri, "*"] diff --git a/sphinx/builders/manpage.py b/sphinx/builders/manpage.py index e53fb5aaf..e3a230b1c 100644 --- a/sphinx/builders/manpage.py +++ b/sphinx/builders/manpage.py @@ -77,9 +77,9 @@ class ManualPageBuilder(Builder): if self.config.man_make_section_directory: dirname = 'man%s' % section ensuredir(path.join(self.outdir, dirname)) - targetname = '%s/%s.%s' % (dirname, name, section) + targetname = f'{dirname}/{name}.{section}' else: - targetname = '%s.%s' % (name, section) + targetname = f'{name}.{section}' logger.info(darkgreen(targetname) + ' { ', nonl=True) destination = FileOutput( @@ -106,7 +106,7 @@ class ManualPageBuilder(Builder): def default_man_pages(config: Config) -> list[tuple[str, str, str, list[str], int]]: """ Better default man_pages settings. """ filename = make_filename_from_project(config.project) - return [(config.root_doc, filename, '%s %s' % (config.project, config.release), + return [(config.root_doc, filename, f'{config.project} {config.release}', [config.author], 1)] diff --git a/sphinx/builders/singlehtml.py b/sphinx/builders/singlehtml.py index a2c9fe1d4..0fdd5b6e6 100644 --- a/sphinx/builders/singlehtml.py +++ b/sphinx/builders/singlehtml.py @@ -89,7 +89,7 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder): new_secnumbers: dict[str, tuple[int, ...]] = {} for docname, secnums in self.env.toc_secnumbers.items(): for id, secnum in secnums.items(): - alias = "%s/%s" % (docname, id) + alias = f"{docname}/{id}" new_secnumbers[alias] = secnum return {self.config.root_doc: new_secnumbers} @@ -108,7 +108,7 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder): # {'foo': {'figure': {'id2': (2,), 'id1': (1,)}}, 'bar': {'figure': {'id1': (3,)}}} for docname, fignumlist in self.env.toc_fignumbers.items(): for figtype, fignums in fignumlist.items(): - alias = "%s/%s" % (docname, figtype) + alias = f"{docname}/{figtype}" new_fignumbers.setdefault(alias, {}) for id, fignum in fignums.items(): new_fignumbers[alias][id] = fignum diff --git a/sphinx/cmd/make_mode.py b/sphinx/cmd/make_mode.py index 3e3663c81..6624903f9 100644 --- a/sphinx/cmd/make_mode.py +++ b/sphinx/cmd/make_mode.py @@ -85,7 +85,7 @@ class Make: print("Please use `make %s' where %s is one of" % ((blue('target'),) * 2)) for osname, bname, description in BUILDERS: if not osname or os.name == osname: - print(' %s %s' % (blue(bname.ljust(10)), description)) + print(f' {blue(bname.ljust(10))} {description}') def build_latexpdf(self) -> int: if self.run_generic_build('latex') > 0: diff --git a/sphinx/cmd/quickstart.py b/sphinx/cmd/quickstart.py index 9e4660ab9..0e714538e 100644 --- a/sphinx/cmd/quickstart.py +++ b/sphinx/cmd/quickstart.py @@ -137,7 +137,7 @@ def do_prompt( ) -> str | bool: while True: if default is not None: - prompt = PROMPT_PREFIX + '%s [%s]: ' % (text, default) + prompt = PROMPT_PREFIX + f'{text} [{default}]: ' else: prompt = PROMPT_PREFIX + text + ': ' if USE_LIBEDIT: @@ -306,7 +306,7 @@ def ask_user(d: dict[str, Any]) -> None: print(__('Indicate which of the following Sphinx extensions should be enabled:')) d['extensions'] = [] for name, description in EXTENSIONS.items(): - if do_prompt('%s: %s (y/n)' % (name, description), 'n', boolean): + if do_prompt(f'{name}: {description} (y/n)', 'n', boolean): d['extensions'].append('sphinx.ext.%s' % name) # Handle conflicting options diff --git a/sphinx/config.py b/sphinx/config.py index 4cc04fc2e..7eb361b1a 100644 --- a/sphinx/config.py +++ b/sphinx/config.py @@ -7,7 +7,7 @@ import traceback import types from collections import OrderedDict from os import getenv, path -from typing import TYPE_CHECKING, Any, Callable, Generator, Iterator, NamedTuple, Optional +from typing import TYPE_CHECKING, Any, Callable, Generator, Iterator, NamedTuple from sphinx.errors import ConfigError, ExtensionError from sphinx.locale import _, __ @@ -164,7 +164,7 @@ class Config: @classmethod def read( cls, confdir: str, overrides: dict | None = None, tags: Tags | None = None - ) -> "Config": + ) -> Config: """Create a Config object from configuration file.""" filename = path.join(confdir, CONFIG_FILENAME) if not path.isfile(filename): @@ -366,7 +366,7 @@ def eval_config_file(filename: str, tags: Tags | None) -> dict[str, Any]: return namespace -def convert_source_suffix(app: "Sphinx", config: Config) -> None: +def convert_source_suffix(app: Sphinx, config: Config) -> None: """Convert old styled source_suffix to new styled one. * old style: str or list @@ -391,7 +391,7 @@ def convert_source_suffix(app: "Sphinx", config: Config) -> None: "But `%r' is given." % source_suffix)) -def convert_highlight_options(app: "Sphinx", config: Config) -> None: +def convert_highlight_options(app: Sphinx, config: Config) -> None: """Convert old styled highlight_options to new styled one. * old style: options @@ -403,7 +403,7 @@ def convert_highlight_options(app: "Sphinx", config: Config) -> None: config.highlight_options = {config.highlight_language: options} # type: ignore -def init_numfig_format(app: "Sphinx", config: Config) -> None: +def init_numfig_format(app: Sphinx, config: Config) -> None: """Initialize :confval:`numfig_format`.""" numfig_format = {'section': _('Section %s'), 'figure': _('Fig. %s'), @@ -415,7 +415,7 @@ def init_numfig_format(app: "Sphinx", config: Config) -> None: config.numfig_format = numfig_format # type: ignore -def correct_copyright_year(app: "Sphinx", config: Config) -> None: +def correct_copyright_year(app: Sphinx, config: Config) -> None: """Correct values of copyright year that are not coherent with the SOURCE_DATE_EPOCH environment variable (if set) @@ -428,7 +428,7 @@ def correct_copyright_year(app: "Sphinx", config: Config) -> None: config[k] = copyright_year_re.sub(replace, config[k]) -def check_confval_types(app: Optional["Sphinx"], config: Config) -> None: +def check_confval_types(app: Sphinx | None, config: Config) -> None: """Check all values for deviation from the default value's type, since that can result in TypeErrors all over the place NB. """ @@ -467,9 +467,8 @@ def check_confval_types(app: Optional["Sphinx"], config: Config) -> None: "expected {permitted}.") wrapped_annotations = [f"`{c.__name__}'" for c in annotations] if len(wrapped_annotations) > 2: - permitted = "{}, or {}".format( - ", ".join(wrapped_annotations[:-1]), - wrapped_annotations[-1]) + permitted = (", ".join(wrapped_annotations[:-1]) + + f", or {wrapped_annotations[-1]}") else: permitted = " or ".join(wrapped_annotations) logger.warning(msg.format(name=confval.name, @@ -483,14 +482,14 @@ def check_confval_types(app: Optional["Sphinx"], config: Config) -> None: default=type(default)), once=True) -def check_primary_domain(app: "Sphinx", config: Config) -> None: +def check_primary_domain(app: Sphinx, config: Config) -> None: primary_domain = config.primary_domain if primary_domain and not app.registry.has_domain(primary_domain): logger.warning(__('primary_domain %r not found, ignored.'), primary_domain) config.primary_domain = None # type: ignore -def check_root_doc(app: "Sphinx", env: "BuildEnvironment", added: set[str], +def check_root_doc(app: Sphinx, env: BuildEnvironment, added: set[str], changed: set[str], removed: set[str]) -> set[str]: """Adjust root_doc to 'contents' to support an old project which does not have any root_doc setting. @@ -505,7 +504,7 @@ def check_root_doc(app: "Sphinx", env: "BuildEnvironment", added: set[str], return changed -def setup(app: "Sphinx") -> dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.connect('config-inited', convert_source_suffix, priority=800) app.connect('config-inited', convert_highlight_options, priority=800) app.connect('config-inited', init_numfig_format, priority=800) diff --git a/sphinx/deprecation.py b/sphinx/deprecation.py index f91ee8b91..4e03aa62c 100644 --- a/sphinx/deprecation.py +++ b/sphinx/deprecation.py @@ -43,13 +43,13 @@ class _ModuleWrapper: canonical_name = self._names.get(name, None) if canonical_name is not None: - warnings.warn( - "The alias '{}.{}' is deprecated, use '{}' instead. Check CHANGES for " - "Sphinx API modifications.".format(self._modname, name, canonical_name), - self._warning, stacklevel=3) + warnings.warn(f"The alias '{self._modname}.{name}' is deprecated, " + f"use '{canonical_name}' instead. " + "Check CHANGES for Sphinx API modifications.", + self._warning, stacklevel=3) else: - warnings.warn("{}.{} is deprecated. Check CHANGES for Sphinx " - "API modifications.".format(self._modname, name), + warnings.warn(f"{self._modname}.{name} is deprecated. " + "Check CHANGES for Sphinx API modifications.", self._warning, stacklevel=3) return self._objects[name] diff --git a/sphinx/directives/__init__.py b/sphinx/directives/__init__.py index c5592e187..4970f2696 100644 --- a/sphinx/directives/__init__.py +++ b/sphinx/directives/__init__.py @@ -323,7 +323,7 @@ class DefaultDomain(SphinxDirective): return [] -def setup(app: "Sphinx") -> dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_config_value("strip_signature_backslash", False, 'env') directives.register_directive('default-role', DefaultRole) directives.register_directive('default-domain', DefaultDomain) diff --git a/sphinx/directives/code.py b/sphinx/directives/code.py index 719703aae..5d54ef1a9 100644 --- a/sphinx/directives/code.py +++ b/sphinx/directives/code.py @@ -470,7 +470,7 @@ class LiteralInclude(SphinxDirective): return [document.reporter.warning(exc, line=self.lineno)] -def setup(app: "Sphinx") -> dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: directives.register_directive('highlight', Highlight) directives.register_directive('code-block', CodeBlock) directives.register_directive('sourcecode', CodeBlock) diff --git a/sphinx/directives/other.py b/sphinx/directives/other.py index febb2b61b..c15a76dc0 100644 --- a/sphinx/directives/other.py +++ b/sphinx/directives/other.py @@ -367,7 +367,7 @@ class Include(BaseInclude, SphinxDirective): return super().run() -def setup(app: "Sphinx") -> dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: directives.register_directive('toctree', TocTree) directives.register_directive('sectionauthor', Author) directives.register_directive('moduleauthor', Author) diff --git a/sphinx/directives/patches.py b/sphinx/directives/patches.py index 6e63308d5..3fd5524b3 100644 --- a/sphinx/directives/patches.py +++ b/sphinx/directives/patches.py @@ -175,7 +175,7 @@ class MathDirective(SphinxDirective): ret.insert(0, target) -def setup(app: "Sphinx") -> dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: directives.register_directive('figure', Figure) directives.register_directive('meta', Meta) directives.register_directive('csv-table', CSVTable) diff --git a/sphinx/domains/__init__.py b/sphinx/domains/__init__.py index 8ea9a1e25..530940546 100644 --- a/sphinx/domains/__init__.py +++ b/sphinx/domains/__init__.py @@ -88,7 +88,7 @@ class Index(ABC): localname: str = None shortname: str = None - def __init__(self, domain: "Domain") -> None: + def __init__(self, domain: Domain) -> None: if self.name is None or self.localname is None: raise SphinxError('Index subclass %s has no valid name or localname' % self.__class__.__name__) @@ -196,7 +196,7 @@ class Domain: #: data version, bump this when the format of `self.data` changes data_version = 0 - def __init__(self, env: "BuildEnvironment") -> None: + def __init__(self, env: BuildEnvironment) -> None: self.env: BuildEnvironment = env self._role_cache: dict[str, Callable] = {} self._directive_cache: dict[str, Callable] = {} @@ -233,7 +233,7 @@ class Domain: std = cast(StandardDomain, self.env.get_domain('std')) for index in self.indices: if index.name and index.localname: - docname = "%s-%s" % (self.name, index.name) + docname = f"{self.name}-{index.name}" std.note_hyperlink_target(docname, docname, '', index.localname) def add_object_type(self, name: str, objtype: ObjType) -> None: @@ -255,7 +255,7 @@ class Domain: return self._role_cache[name] if name not in self.roles: return None - fullname = '%s:%s' % (self.name, name) + fullname = f'{self.name}:{name}' def role_adapter(typ: str, rawtext: str, text: str, lineno: int, inliner: Inliner, options: dict = {}, content: list[str] = [] @@ -273,7 +273,7 @@ class Domain: return self._directive_cache[name] if name not in self.directives: return None - fullname = '%s:%s' % (self.name, name) + fullname = f'{self.name}:{name}' BaseDirective = self.directives[name] class DirectiveAdapter(BaseDirective): # type: ignore @@ -297,7 +297,7 @@ class Domain: 'to be able to do parallel builds!' % self.__class__) - def process_doc(self, env: "BuildEnvironment", docname: str, + def process_doc(self, env: BuildEnvironment, docname: str, document: nodes.document) -> None: """Process a document after it is read by the environment.""" pass @@ -312,7 +312,7 @@ class Domain: """ pass - def resolve_xref(self, env: "BuildEnvironment", fromdocname: str, builder: "Builder", + def resolve_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder, typ: str, target: str, node: pending_xref, contnode: Element ) -> Element | None: """Resolve the pending_xref *node* with the given *typ* and *target*. @@ -330,7 +330,7 @@ class Domain: """ pass - def resolve_any_xref(self, env: "BuildEnvironment", fromdocname: str, builder: "Builder", + def resolve_any_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder, target: str, node: pending_xref, contnode: Element ) -> list[tuple[str, Element]]: """Resolve the pending_xref *node* with the given *target*. diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py index 567911ec3..353a7d14a 100644 --- a/sphinx/domains/c.py +++ b/sphinx/domains/c.py @@ -3,7 +3,7 @@ from __future__ import annotations import re -from typing import Any, Callable, Generator, Iterator, Optional, TypeVar, Union, cast +from typing import Any, Callable, Generator, Iterator, TypeVar, Union, cast from docutils import nodes from docutils.nodes import Element, Node, TextElement, system_message @@ -105,7 +105,7 @@ _simple_type_specifiers_re = re.compile(r"""(?x) class _DuplicateSymbolError(Exception): - def __init__(self, symbol: "Symbol", declaration: "ASTDeclaration") -> None: + def __init__(self, symbol: Symbol, declaration: ASTDeclaration) -> None: assert symbol assert declaration self.symbol = symbol @@ -117,7 +117,7 @@ class _DuplicateSymbolError(Exception): class ASTBase(ASTBaseBase): def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: raise NotImplementedError(repr(self)) @@ -144,8 +144,8 @@ class ASTIdentifier(ASTBaseBase): def get_display_string(self) -> str: return "[anonymous]" if self.is_anon() else self.identifier - def describe_signature(self, signode: TextElement, mode: str, env: "BuildEnvironment", - prefix: str, symbol: "Symbol") -> None: + def describe_signature(self, signode: TextElement, mode: str, env: BuildEnvironment, + prefix: str, symbol: Symbol) -> None: # note: slightly different signature of describe_signature due to the prefix verify_description_mode(mode) if self.is_anon(): @@ -178,7 +178,7 @@ class ASTNestedName(ASTBase): self.rooted = rooted @property - def name(self) -> "ASTNestedName": + def name(self) -> ASTNestedName: return self def get_id(self, version: int) -> str: @@ -192,7 +192,7 @@ class ASTNestedName(ASTBase): return res def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) # just print the name part, with template args, not template params if mode == 'noneIsName': @@ -274,7 +274,7 @@ class ASTBooleanLiteral(ASTLiteral): return 'false' def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: txt = str(self) signode += addnodes.desc_sig_keyword(txt, txt) @@ -287,7 +287,7 @@ class ASTNumberLiteral(ASTLiteral): return self.data def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: txt = str(self) signode += addnodes.desc_sig_literal_number(txt, txt) @@ -309,7 +309,7 @@ class ASTCharLiteral(ASTLiteral): return self.prefix + "'" + self.data + "'" def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: txt = str(self) signode += addnodes.desc_sig_literal_char(txt, txt) @@ -322,7 +322,7 @@ class ASTStringLiteral(ASTLiteral): return self.data def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: txt = str(self) signode += addnodes.desc_sig_literal_string(txt, txt) @@ -339,7 +339,7 @@ class ASTIdExpression(ASTExpression): return self.name.get_id(version) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: self.name.describe_signature(signode, mode, env, symbol) @@ -354,7 +354,7 @@ class ASTParenExpr(ASTExpression): return self.expr.get_id(version) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_punctuation('(', '(') self.expr.describe_signature(signode, mode, env, symbol) signode += addnodes.desc_sig_punctuation(')', ')') @@ -368,14 +368,14 @@ class ASTPostfixOp(ASTBase): class ASTPostfixCallExpr(ASTPostfixOp): - def __init__(self, lst: Union["ASTParenExprList", "ASTBracedInitList"]) -> None: + def __init__(self, lst: ASTParenExprList | ASTBracedInitList) -> None: self.lst = lst def _stringify(self, transform: StringifyTransform) -> str: return transform(self.lst) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: self.lst.describe_signature(signode, mode, env, symbol) @@ -387,7 +387,7 @@ class ASTPostfixArray(ASTPostfixOp): return '[' + transform(self.expr) + ']' def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_punctuation('[', '[') self.expr.describe_signature(signode, mode, env, symbol) signode += addnodes.desc_sig_punctuation(']', ']') @@ -398,7 +398,7 @@ class ASTPostfixInc(ASTPostfixOp): return '++' def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_operator('++', '++') @@ -407,7 +407,7 @@ class ASTPostfixDec(ASTPostfixOp): return '--' def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_operator('--', '--') @@ -419,7 +419,7 @@ class ASTPostfixMemberOfPointer(ASTPostfixOp): return '->' + transform(self.name) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_operator('->', '->') self.name.describe_signature(signode, 'noneIsName', env, symbol) @@ -436,7 +436,7 @@ class ASTPostfixExpr(ASTExpression): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: self.prefix.describe_signature(signode, mode, env, symbol) for p in self.postFixes: p.describe_signature(signode, mode, env, symbol) @@ -457,7 +457,7 @@ class ASTUnaryOpExpr(ASTExpression): return self.op + transform(self.expr) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: if self.op[0] in 'cn': signode += addnodes.desc_sig_keyword(self.op, self.op) signode += addnodes.desc_sig_space() @@ -474,7 +474,7 @@ class ASTSizeofType(ASTExpression): return "sizeof(" + transform(self.typ) + ")" def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_keyword('sizeof', 'sizeof') signode += addnodes.desc_sig_punctuation('(', '(') self.typ.describe_signature(signode, mode, env, symbol) @@ -489,21 +489,21 @@ class ASTSizeofExpr(ASTExpression): return "sizeof " + transform(self.expr) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_keyword('sizeof', 'sizeof') signode += addnodes.desc_sig_space() self.expr.describe_signature(signode, mode, env, symbol) class ASTAlignofExpr(ASTExpression): - def __init__(self, typ: "ASTType"): + def __init__(self, typ: ASTType): self.typ = typ def _stringify(self, transform: StringifyTransform) -> str: return "alignof(" + transform(self.typ) + ")" def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_keyword('alignof', 'alignof') signode += addnodes.desc_sig_punctuation('(', '(') self.typ.describe_signature(signode, mode, env, symbol) @@ -514,7 +514,7 @@ class ASTAlignofExpr(ASTExpression): ################################################################################ class ASTCastExpr(ASTExpression): - def __init__(self, typ: "ASTType", expr: ASTExpression): + def __init__(self, typ: ASTType, expr: ASTExpression): self.typ = typ self.expr = expr @@ -526,7 +526,7 @@ class ASTCastExpr(ASTExpression): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_punctuation('(', '(') self.typ.describe_signature(signode, mode, env, symbol) signode += addnodes.desc_sig_punctuation(')', ')') @@ -551,7 +551,7 @@ class ASTBinOpExpr(ASTBase): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: self.exprs[0].describe_signature(signode, mode, env, symbol) for i in range(1, len(self.exprs)): signode += addnodes.desc_sig_space() @@ -582,7 +582,7 @@ class ASTAssignmentExpr(ASTExpression): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: self.exprs[0].describe_signature(signode, mode, env, symbol) for i in range(1, len(self.exprs)): signode += addnodes.desc_sig_space() @@ -606,7 +606,7 @@ class ASTFallbackExpr(ASTExpression): return str(self.expr) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += nodes.literal(self.expr, self.expr) @@ -627,7 +627,7 @@ class ASTTrailingTypeSpecFundamental(ASTTrailingTypeSpec): return ' '.join(self.names) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: first = True for n in self.names: if not first: @@ -655,7 +655,7 @@ class ASTTrailingTypeSpecName(ASTTrailingTypeSpec): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: if self.prefix: signode += addnodes.desc_sig_keyword(self.prefix, self.prefix) signode += addnodes.desc_sig_space() @@ -663,11 +663,11 @@ class ASTTrailingTypeSpecName(ASTTrailingTypeSpec): class ASTFunctionParameter(ASTBase): - def __init__(self, arg: Optional["ASTTypeWithInit"], ellipsis: bool = False) -> None: + def __init__(self, arg: ASTTypeWithInit | None, ellipsis: bool = False) -> None: self.arg = arg self.ellipsis = ellipsis - def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str: + def get_id(self, version: int, objectType: str, symbol: Symbol) -> str: # the anchor will be our parent return symbol.parent.declaration.get_id(version, prefixed=False) @@ -678,7 +678,7 @@ class ASTFunctionParameter(ASTBase): return transform(self.arg) def describe_signature(self, signode: Any, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) if self.ellipsis: signode += addnodes.desc_sig_punctuation('...', '...') @@ -711,7 +711,7 @@ class ASTParameters(ASTBase): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) # only use the desc_parameterlist for the outer list, not for inner lists if mode == 'lastIsName': @@ -748,7 +748,7 @@ class ASTDeclSpecsSimple(ASTBaseBase): self.const = const self.attrs = attrs - def mergeWith(self, other: "ASTDeclSpecsSimple") -> "ASTDeclSpecsSimple": + def mergeWith(self, other: ASTDeclSpecsSimple) -> ASTDeclSpecsSimple: if not other: return self return ASTDeclSpecsSimple(self.storage or other.storage, @@ -832,7 +832,7 @@ class ASTDeclSpecs(ASTBase): return "".join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) modifiers: list[Node] = [] @@ -887,7 +887,7 @@ class ASTArray(ASTBase): return '[' + ' '.join(el) + ']' def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) signode += addnodes.desc_sig_punctuation('[', '[') addSpace = False @@ -959,7 +959,7 @@ class ASTDeclaratorNameParam(ASTDeclarator): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) if self.declId: self.declId.describe_signature(signode, mode, env, symbol) @@ -992,7 +992,7 @@ class ASTDeclaratorNameBitField(ASTDeclarator): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) if self.declId: self.declId.describe_signature(signode, mode, env, symbol) @@ -1047,7 +1047,7 @@ class ASTDeclaratorPtr(ASTDeclarator): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) signode += addnodes.desc_sig_punctuation('*', '*') self.attrs.describe_signature(signode) @@ -1100,7 +1100,7 @@ class ASTDeclaratorParen(ASTDeclarator): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) signode += addnodes.desc_sig_punctuation('(', '(') self.inner.describe_signature(signode, mode, env, symbol) @@ -1120,7 +1120,7 @@ class ASTParenExprList(ASTBaseParenExprList): return '(%s)' % ', '.join(exprs) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) signode += addnodes.desc_sig_punctuation('(', '(') first = True @@ -1140,12 +1140,12 @@ class ASTBracedInitList(ASTBase): self.trailingComma = trailingComma def _stringify(self, transform: StringifyTransform) -> str: - exprs = [transform(e) for e in self.exprs] + exprs = ', '.join(transform(e) for e in self.exprs) trailingComma = ',' if self.trailingComma else '' - return '{%s%s}' % (', '.join(exprs), trailingComma) + return f'{{{exprs}{trailingComma}}}' def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) signode += addnodes.desc_sig_punctuation('{', '{') first = True @@ -1175,7 +1175,7 @@ class ASTInitializer(ASTBase): return val def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) if self.hasAssign: signode += addnodes.desc_sig_space() @@ -1195,7 +1195,7 @@ class ASTType(ASTBase): def name(self) -> ASTNestedName: return self.decl.name - def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str: + def get_id(self, version: int, objectType: str, symbol: Symbol) -> str: return symbol.get_full_nested_name().get_id(version) @property @@ -1218,7 +1218,7 @@ class ASTType(ASTBase): return 'type' def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) self.declSpecs.describe_signature(signode, 'markType', env, symbol) if (self.decl.require_space_after_declSpecs() and @@ -1240,7 +1240,7 @@ class ASTTypeWithInit(ASTBase): def name(self) -> ASTNestedName: return self.type.name - def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str: + def get_id(self, version: int, objectType: str, symbol: Symbol) -> str: return self.type.get_id(version, objectType, symbol) def _stringify(self, transform: StringifyTransform) -> str: @@ -1251,7 +1251,7 @@ class ASTTypeWithInit(ASTBase): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) self.type.describe_signature(signode, mode, env, symbol) if self.init: @@ -1274,7 +1274,7 @@ class ASTMacroParameter(ASTBase): return transform(self.arg) def describe_signature(self, signode: Any, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) if self.ellipsis: signode += addnodes.desc_sig_punctuation('...', '...') @@ -1294,7 +1294,7 @@ class ASTMacro(ASTBase): def name(self) -> ASTNestedName: return self.ident - def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str: + def get_id(self, version: int, objectType: str, symbol: Symbol) -> str: return symbol.get_full_nested_name().get_id(version) def _stringify(self, transform: StringifyTransform) -> str: @@ -1312,7 +1312,7 @@ class ASTMacro(ASTBase): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) self.ident.describe_signature(signode, mode, env, symbol) if self.args is None: @@ -1329,14 +1329,14 @@ class ASTStruct(ASTBase): def __init__(self, name: ASTNestedName) -> None: self.name = name - def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str: + def get_id(self, version: int, objectType: str, symbol: Symbol) -> str: return symbol.get_full_nested_name().get_id(version) def _stringify(self, transform: StringifyTransform) -> str: return transform(self.name) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) self.name.describe_signature(signode, mode, env, symbol=symbol) @@ -1345,14 +1345,14 @@ class ASTUnion(ASTBase): def __init__(self, name: ASTNestedName) -> None: self.name = name - def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str: + def get_id(self, version: int, objectType: str, symbol: Symbol) -> str: return symbol.get_full_nested_name().get_id(version) def _stringify(self, transform: StringifyTransform) -> str: return transform(self.name) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) self.name.describe_signature(signode, mode, env, symbol=symbol) @@ -1361,14 +1361,14 @@ class ASTEnum(ASTBase): def __init__(self, name: ASTNestedName) -> None: self.name = name - def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str: + def get_id(self, version: int, objectType: str, symbol: Symbol) -> str: return symbol.get_full_nested_name().get_id(version) def _stringify(self, transform: StringifyTransform) -> str: return transform(self.name) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) self.name.describe_signature(signode, mode, env, symbol=symbol) @@ -1380,7 +1380,7 @@ class ASTEnumerator(ASTBase): self.init = init self.attrs = attrs - def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str: + def get_id(self, version: int, objectType: str, symbol: Symbol) -> str: return symbol.get_full_nested_name().get_id(version) def _stringify(self, transform: StringifyTransform) -> str: @@ -1394,7 +1394,7 @@ class ASTEnumerator(ASTBase): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) self.name.describe_signature(signode, mode, env, symbol) if len(self.attrs) != 0: @@ -1417,7 +1417,7 @@ class ASTDeclaration(ASTBaseBase): # set by CObject._add_enumerator_to_parent self.enumeratorScopedSymbol: Symbol = None - def clone(self) -> "ASTDeclaration": + def clone(self) -> ASTDeclaration: return ASTDeclaration(self.objectType, self.directiveType, self.declaration.clone(), self.semicolon) @@ -1452,7 +1452,7 @@ class ASTDeclaration(ASTBaseBase): return res def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", options: dict) -> None: + env: BuildEnvironment, options: dict) -> None: verify_description_mode(mode) assert self.symbol # The caller of the domain added a desc_signature node. @@ -1495,7 +1495,7 @@ class ASTDeclaration(ASTBaseBase): class SymbolLookupResult: - def __init__(self, symbols: Iterator["Symbol"], parentSymbol: "Symbol", + def __init__(self, symbols: Iterator[Symbol], parentSymbol: Symbol, ident: ASTIdentifier) -> None: self.symbols = symbols self.parentSymbol = parentSymbol @@ -1507,8 +1507,8 @@ class LookupKey: self.data = data def __str__(self) -> str: - return '[{}]'.format(', '.join("({}, {})".format( - ident, id_) for ident, id_ in self.data)) + inner = ', '.join(f"({ident}, {id_})" for ident, id_ in self.data) + return f'[{inner}]' class Symbol: @@ -1547,7 +1547,7 @@ class Symbol: else: return super().__setattr__(key, value) - def __init__(self, parent: "Symbol", ident: ASTIdentifier, + def __init__(self, parent: Symbol, ident: ASTIdentifier, declaration: ASTDeclaration, docname: str, line: int) -> None: self.parent = parent # declarations in a single directive are linked together @@ -1632,24 +1632,24 @@ class Symbol: sChild.siblingAbove = None sChild.siblingBelow = None - def get_all_symbols(self) -> Iterator["Symbol"]: + def get_all_symbols(self) -> Iterator[Symbol]: yield self for sChild in self._children: yield from sChild.get_all_symbols() @property - def children(self) -> Iterator["Symbol"]: + def children(self) -> Iterator[Symbol]: yield from self._children @property - def children_recurse_anon(self) -> Iterator["Symbol"]: + def children_recurse_anon(self) -> Iterator[Symbol]: for c in self._children: yield c if not c.ident.is_anon(): continue yield from c.children_recurse_anon - def get_lookup_key(self) -> "LookupKey": + def get_lookup_key(self) -> LookupKey: # The pickle files for the environment and for each document are distinct. # The environment has all the symbols, but the documents has xrefs that # must know their scope. A lookup key is essentially a specification of @@ -1682,7 +1682,7 @@ class Symbol: return ASTNestedName(names, rooted=False) def _find_first_named_symbol(self, ident: ASTIdentifier, - matchSelf: bool, recurseInAnon: bool) -> "Symbol": + matchSelf: bool, recurseInAnon: bool) -> Symbol: # TODO: further simplification from C++ to C if Symbol.debug_lookup: Symbol.debug_print("_find_first_named_symbol ->") @@ -1695,7 +1695,7 @@ class Symbol: def _find_named_symbols(self, ident: ASTIdentifier, matchSelf: bool, recurseInAnon: bool, - searchInSiblings: bool) -> Iterator["Symbol"]: + searchInSiblings: bool) -> Iterator[Symbol]: # TODO: further simplification from C++ to C if Symbol.debug_lookup: Symbol.debug_indent += 1 @@ -1708,7 +1708,7 @@ class Symbol: Symbol.debug_print("recurseInAnon: ", recurseInAnon) Symbol.debug_print("searchInSiblings: ", searchInSiblings) - def candidates() -> Generator["Symbol", None, None]: + def candidates() -> Generator[Symbol, None, None]: s = self if Symbol.debug_lookup: Symbol.debug_print("searching in self:") @@ -1744,7 +1744,7 @@ class Symbol: Symbol.debug_indent -= 2 def _symbol_lookup(self, nestedName: ASTNestedName, - onMissingQualifiedSymbol: Callable[["Symbol", ASTIdentifier], "Symbol"], + onMissingQualifiedSymbol: Callable[[Symbol, ASTIdentifier], Symbol], ancestorLookupType: str, matchSelf: bool, recurseInAnon: bool, searchInSiblings: bool) -> SymbolLookupResult: # TODO: further simplification from C++ to C @@ -1816,7 +1816,7 @@ class Symbol: return SymbolLookupResult(symbols, parentSymbol, ident) def _add_symbols(self, nestedName: ASTNestedName, - declaration: ASTDeclaration, docname: str, line: int) -> "Symbol": + declaration: ASTDeclaration, docname: str, line: int) -> Symbol: # TODO: further simplification from C++ to C # Used for adding a whole path of symbols, where the last may or may not # be an actual declaration. @@ -1829,7 +1829,7 @@ class Symbol: Symbol.debug_print("decl: ", declaration) Symbol.debug_print(f"location: {docname}:{line}") - def onMissingQualifiedSymbol(parentSymbol: "Symbol", ident: ASTIdentifier) -> "Symbol": + def onMissingQualifiedSymbol(parentSymbol: Symbol, ident: ASTIdentifier) -> Symbol: if Symbol.debug_lookup: Symbol.debug_indent += 1 Symbol.debug_print("_add_symbols, onMissingQualifiedSymbol:") @@ -1900,7 +1900,7 @@ class Symbol: # First check if one of those with a declaration matches. # If it's a function, we need to compare IDs, # otherwise there should be only one symbol with a declaration. - def makeCandSymbol() -> "Symbol": + def makeCandSymbol() -> Symbol: if Symbol.debug_lookup: Symbol.debug_print("begin: creating candidate symbol") symbol = Symbol(parent=lookupResult.parentSymbol, @@ -1916,7 +1916,7 @@ class Symbol: else: candSymbol = makeCandSymbol() - def handleDuplicateDeclaration(symbol: "Symbol", candSymbol: "Symbol") -> None: + def handleDuplicateDeclaration(symbol: Symbol, candSymbol: Symbol) -> None: if Symbol.debug_lookup: Symbol.debug_indent += 1 Symbol.debug_print("redeclaration") @@ -1977,8 +1977,8 @@ class Symbol: symbol._fill_empty(declaration, docname, line) return symbol - def merge_with(self, other: "Symbol", docnames: list[str], - env: "BuildEnvironment") -> None: + def merge_with(self, other: Symbol, docnames: list[str], + env: BuildEnvironment) -> None: if Symbol.debug_lookup: Symbol.debug_indent += 1 Symbol.debug_print("merge_with:") @@ -2013,7 +2013,7 @@ class Symbol: if Symbol.debug_lookup: Symbol.debug_indent -= 1 - def add_name(self, nestedName: ASTNestedName) -> "Symbol": + def add_name(self, nestedName: ASTNestedName) -> Symbol: if Symbol.debug_lookup: Symbol.debug_indent += 1 Symbol.debug_print("add_name:") @@ -2023,7 +2023,7 @@ class Symbol: return res def add_declaration(self, declaration: ASTDeclaration, - docname: str, line: int) -> "Symbol": + docname: str, line: int) -> Symbol: if Symbol.debug_lookup: Symbol.debug_indent += 1 Symbol.debug_print("add_declaration:") @@ -2038,7 +2038,7 @@ class Symbol: def find_identifier(self, ident: ASTIdentifier, matchSelf: bool, recurseInAnon: bool, searchInSiblings: bool - ) -> "Symbol": + ) -> Symbol: if Symbol.debug_lookup: Symbol.debug_indent += 1 Symbol.debug_print("find_identifier:") @@ -2067,7 +2067,7 @@ class Symbol: current = current.siblingAbove return None - def direct_lookup(self, key: "LookupKey") -> "Symbol": + def direct_lookup(self, key: LookupKey) -> Symbol: if Symbol.debug_lookup: Symbol.debug_indent += 1 Symbol.debug_print("direct_lookup:") @@ -2096,14 +2096,14 @@ class Symbol: return s def find_declaration(self, nestedName: ASTNestedName, typ: str, - matchSelf: bool, recurseInAnon: bool) -> "Symbol": + matchSelf: bool, recurseInAnon: bool) -> Symbol: # templateShorthand: missing template parameter lists for templates is ok if Symbol.debug_lookup: Symbol.debug_indent += 1 Symbol.debug_print("find_declaration:") - def onMissingQualifiedSymbol(parentSymbol: "Symbol", - ident: ASTIdentifier) -> "Symbol": + def onMissingQualifiedSymbol(parentSymbol: Symbol, + ident: ASTIdentifier) -> Symbol: return None lookupResult = self._symbol_lookup(nestedName, @@ -2270,7 +2270,7 @@ class DefinitionParser(BaseParser): if self.skip_string(close): break if not self.skip_string_and_ws(','): - self.fail("Error in %s, expected ',' or '%s'." % (name, close)) + self.fail(f"Error in {name}, expected ',' or '{close}'.") if self.current_char == close and close == '}': self.pos += 1 trailingComma = True @@ -3446,7 +3446,7 @@ class CNamespacePopObject(SphinxDirective): class AliasNode(nodes.Element): def __init__(self, sig: str, aliasOptions: dict, - document: Any, env: "BuildEnvironment" = None, + document: Any, env: BuildEnvironment = None, parentKey: LookupKey = None) -> None: super().__init__() self.sig = sig @@ -3462,7 +3462,7 @@ class AliasNode(nodes.Element): assert parentKey is not None self.parentKey = parentKey - def copy(self) -> 'AliasNode': + def copy(self) -> AliasNode: return self.__class__(self.sig, self.aliasOptions, self.document, env=None, parentKey=self.parentKey) diff --git a/sphinx/domains/changeset.py b/sphinx/domains/changeset.py index 8320b82d9..22e625f42 100644 --- a/sphinx/domains/changeset.py +++ b/sphinx/domains/changeset.py @@ -138,7 +138,7 @@ class ChangeSetDomain(Domain): changes.append(changeset) def process_doc( - self, env: "BuildEnvironment", docname: str, document: nodes.document + self, env: BuildEnvironment, docname: str, document: nodes.document ) -> None: pass # nothing to do here. All changesets are registered on calling directive. @@ -146,7 +146,7 @@ class ChangeSetDomain(Domain): return self.changesets.get(version, []) -def setup(app: "Sphinx") -> dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_domain(ChangeSetDomain) app.add_directive('deprecated', VersionChange) app.add_directive('versionadded', VersionChange) diff --git a/sphinx/domains/citation.py b/sphinx/domains/citation.py index 668c2ddc6..b0053de21 100644 --- a/sphinx/domains/citation.py +++ b/sphinx/domains/citation.py @@ -80,7 +80,7 @@ class CitationDomain(Domain): logger.warning(__('Citation [%s] is not referenced.'), name, type='ref', subtype='citation', location=(docname, lineno)) - def resolve_xref(self, env: "BuildEnvironment", fromdocname: str, builder: "Builder", + def resolve_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder, typ: str, target: str, node: pending_xref, contnode: Element ) -> Element | None: docname, labelid, lineno = self.citations.get(target, ('', '', 0)) @@ -90,7 +90,7 @@ class CitationDomain(Domain): return make_refnode(builder, fromdocname, docname, labelid, contnode) - def resolve_any_xref(self, env: "BuildEnvironment", fromdocname: str, builder: "Builder", + def resolve_any_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder, target: str, node: pending_xref, contnode: Element ) -> list[tuple[str, Element]]: refnode = self.resolve_xref(env, fromdocname, builder, 'ref', target, node, contnode) @@ -140,7 +140,7 @@ class CitationReferenceTransform(SphinxTransform): domain.note_citation_reference(ref) -def setup(app: "Sphinx") -> dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_domain(CitationDomain) app.add_transform(CitationDefinitionTransform) app.add_transform(CitationReferenceTransform) diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py index 77b2598ad..bec29bada 100644 --- a/sphinx/domains/cpp.py +++ b/sphinx/domains/cpp.py @@ -3,7 +3,7 @@ from __future__ import annotations import re -from typing import Any, Callable, Generator, Iterator, Optional, TypeVar, Union +from typing import Any, Callable, Generator, Iterator, TypeVar from docutils import nodes from docutils.nodes import Element, Node, TextElement, system_message @@ -573,7 +573,7 @@ _id_explicit_cast = { class _DuplicateSymbolError(Exception): - def __init__(self, symbol: "Symbol", declaration: "ASTDeclaration") -> None: + def __init__(self, symbol: Symbol, declaration: ASTDeclaration) -> None: assert symbol assert declaration self.symbol = symbol @@ -626,8 +626,8 @@ class ASTIdentifier(ASTBase): def get_display_string(self) -> str: return "[anonymous]" if self.is_anon() else self.identifier - def describe_signature(self, signode: TextElement, mode: str, env: "BuildEnvironment", - prefix: str, templateArgs: str, symbol: "Symbol") -> None: + def describe_signature(self, signode: TextElement, mode: str, env: BuildEnvironment, + prefix: str, templateArgs: str, symbol: Symbol) -> None: verify_description_mode(mode) if self.is_anon(): node = addnodes.desc_sig_name(text="[anonymous]") @@ -669,8 +669,8 @@ class ASTIdentifier(ASTBase): class ASTNestedNameElement(ASTBase): - def __init__(self, identOrOp: Union[ASTIdentifier, "ASTOperator"], - templateArgs: "ASTTemplateArgs") -> None: + def __init__(self, identOrOp: ASTIdentifier | ASTOperator, + templateArgs: ASTTemplateArgs) -> None: self.identOrOp = identOrOp self.templateArgs = templateArgs @@ -690,7 +690,7 @@ class ASTNestedNameElement(ASTBase): return res def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", prefix: str, symbol: "Symbol") -> None: + env: BuildEnvironment, prefix: str, symbol: Symbol) -> None: tArgs = str(self.templateArgs) if self.templateArgs is not None else '' self.identOrOp.describe_signature(signode, mode, env, prefix, tArgs, symbol) if self.templateArgs is not None: @@ -707,7 +707,7 @@ class ASTNestedName(ASTBase): self.rooted = rooted @property - def name(self) -> "ASTNestedName": + def name(self) -> ASTNestedName: return self def num_templates(self) -> int: @@ -750,7 +750,7 @@ class ASTNestedName(ASTBase): return '::'.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) # just print the name part, with template args, not template params if mode == 'noneIsName': @@ -839,7 +839,7 @@ class ASTExpression(ASTBase): raise NotImplementedError(repr(self)) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: raise NotImplementedError(repr(self)) @@ -858,7 +858,7 @@ class ASTPointerLiteral(ASTLiteral): return 'LDnE' def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_keyword('nullptr', 'nullptr') @@ -879,7 +879,7 @@ class ASTBooleanLiteral(ASTLiteral): return 'L0E' def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_keyword(str(self), str(self)) @@ -895,7 +895,7 @@ class ASTNumberLiteral(ASTLiteral): return "L%sE" % self.data.replace("'", "") def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_literal_number(self.data, self.data) @@ -911,7 +911,7 @@ class ASTStringLiteral(ASTLiteral): return "LA%d_KcE" % (len(self.data) - 2) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_literal_string(self.data, self.data) @@ -938,7 +938,7 @@ class ASTCharLiteral(ASTLiteral): return self.type + str(self.value) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: if self.prefix is not None: signode += addnodes.desc_sig_keyword(self.prefix, self.prefix) txt = "'" + self.data + "'" @@ -958,7 +958,7 @@ class ASTUserDefinedLiteral(ASTLiteral): return f'clL_Zli{self.ident.get_id(version)}E{self.literal.get_id(version)}E' def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: self.literal.describe_signature(signode, mode, env, symbol) self.ident.describe_signature(signode, "udl", env, "", "", symbol) @@ -973,7 +973,7 @@ class ASTThisLiteral(ASTExpression): return "fpT" def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_keyword('this', 'this') @@ -1023,7 +1023,7 @@ class ASTFoldExpr(ASTExpression): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_punctuation('(', '(') if self.leftExpr: self.leftExpr.describe_signature(signode, mode, env, symbol) @@ -1050,7 +1050,7 @@ class ASTParenExpr(ASTExpression): return self.expr.get_id(version) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_punctuation('(', '(') self.expr.describe_signature(signode, mode, env, symbol) signode += addnodes.desc_sig_punctuation(')', ')') @@ -1068,7 +1068,7 @@ class ASTIdExpression(ASTExpression): return self.name.get_id(version) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: self.name.describe_signature(signode, mode, env, symbol) @@ -1080,7 +1080,7 @@ class ASTPostfixOp(ASTBase): raise NotImplementedError(repr(self)) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: raise NotImplementedError(repr(self)) @@ -1095,7 +1095,7 @@ class ASTPostfixArray(ASTPostfixOp): return 'ix' + idPrefix + self.expr.get_id(version) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_punctuation('[', '[') self.expr.describe_signature(signode, mode, env, symbol) signode += addnodes.desc_sig_punctuation(']', ']') @@ -1112,7 +1112,7 @@ class ASTPostfixMember(ASTPostfixOp): return 'dt' + idPrefix + self.name.get_id(version) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_punctuation('.', '.') self.name.describe_signature(signode, 'noneIsName', env, symbol) @@ -1128,7 +1128,7 @@ class ASTPostfixMemberOfPointer(ASTPostfixOp): return 'pt' + idPrefix + self.name.get_id(version) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_operator('->', '->') self.name.describe_signature(signode, 'noneIsName', env, symbol) @@ -1141,7 +1141,7 @@ class ASTPostfixInc(ASTPostfixOp): return 'pp' + idPrefix def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_operator('++', '++') @@ -1153,12 +1153,12 @@ class ASTPostfixDec(ASTPostfixOp): return 'mm' + idPrefix def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_operator('--', '--') class ASTPostfixCallExpr(ASTPostfixOp): - def __init__(self, lst: Union["ASTParenExprList", "ASTBracedInitList"]) -> None: + def __init__(self, lst: ASTParenExprList | ASTBracedInitList) -> None: self.lst = lst def _stringify(self, transform: StringifyTransform) -> str: @@ -1172,12 +1172,12 @@ class ASTPostfixCallExpr(ASTPostfixOp): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: self.lst.describe_signature(signode, mode, env, symbol) class ASTPostfixExpr(ASTExpression): - def __init__(self, prefix: "ASTType", postFixes: list[ASTPostfixOp]): + def __init__(self, prefix: ASTType, postFixes: list[ASTPostfixOp]): self.prefix = prefix self.postFixes = postFixes @@ -1194,14 +1194,14 @@ class ASTPostfixExpr(ASTExpression): return id def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: self.prefix.describe_signature(signode, mode, env, symbol) for p in self.postFixes: p.describe_signature(signode, mode, env, symbol) class ASTExplicitCast(ASTExpression): - def __init__(self, cast: str, typ: "ASTType", expr: ASTExpression): + def __init__(self, cast: str, typ: ASTType, expr: ASTExpression): assert cast in _id_explicit_cast self.cast = cast self.typ = typ @@ -1222,7 +1222,7 @@ class ASTExplicitCast(ASTExpression): self.expr.get_id(version)) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_keyword(self.cast, self.cast) signode += addnodes.desc_sig_punctuation('<', '<') self.typ.describe_signature(signode, mode, env, symbol) @@ -1233,7 +1233,7 @@ class ASTExplicitCast(ASTExpression): class ASTTypeId(ASTExpression): - def __init__(self, typeOrExpr: Union["ASTType", ASTExpression], isType: bool): + def __init__(self, typeOrExpr: ASTType | ASTExpression, isType: bool): self.typeOrExpr = typeOrExpr self.isType = isType @@ -1245,7 +1245,7 @@ class ASTTypeId(ASTExpression): return prefix + self.typeOrExpr.get_id(version) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_keyword('typeid', 'typeid') signode += addnodes.desc_sig_punctuation('(', '(') self.typeOrExpr.describe_signature(signode, mode, env, symbol) @@ -1270,7 +1270,7 @@ class ASTUnaryOpExpr(ASTExpression): return _id_operator_unary_v2[self.op] + self.expr.get_id(version) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: if self.op[0] in 'cn': signode += addnodes.desc_sig_keyword(self.op, self.op) signode += addnodes.desc_sig_space() @@ -1290,7 +1290,7 @@ class ASTSizeofParamPack(ASTExpression): return 'sZ' + self.identifier.get_id(version) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_keyword('sizeof', 'sizeof') signode += addnodes.desc_sig_punctuation('...', '...') signode += addnodes.desc_sig_punctuation('(', '(') @@ -1300,7 +1300,7 @@ class ASTSizeofParamPack(ASTExpression): class ASTSizeofType(ASTExpression): - def __init__(self, typ: "ASTType"): + def __init__(self, typ: ASTType): self.typ = typ def _stringify(self, transform: StringifyTransform) -> str: @@ -1310,7 +1310,7 @@ class ASTSizeofType(ASTExpression): return 'st' + self.typ.get_id(version) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_keyword('sizeof', 'sizeof') signode += addnodes.desc_sig_punctuation('(', '(') self.typ.describe_signature(signode, mode, env, symbol) @@ -1328,14 +1328,14 @@ class ASTSizeofExpr(ASTExpression): return 'sz' + self.expr.get_id(version) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_keyword('sizeof', 'sizeof') signode += addnodes.desc_sig_space() self.expr.describe_signature(signode, mode, env, symbol) class ASTAlignofExpr(ASTExpression): - def __init__(self, typ: "ASTType"): + def __init__(self, typ: ASTType): self.typ = typ def _stringify(self, transform: StringifyTransform) -> str: @@ -1345,7 +1345,7 @@ class ASTAlignofExpr(ASTExpression): return 'at' + self.typ.get_id(version) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_keyword('alignof', 'alignof') signode += addnodes.desc_sig_punctuation('(', '(') self.typ.describe_signature(signode, mode, env, symbol) @@ -1363,7 +1363,7 @@ class ASTNoexceptExpr(ASTExpression): return 'nx' + self.expr.get_id(version) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_keyword('noexcept', 'noexcept') signode += addnodes.desc_sig_punctuation('(', '(') self.expr.describe_signature(signode, mode, env, symbol) @@ -1371,8 +1371,8 @@ class ASTNoexceptExpr(ASTExpression): class ASTNewExpr(ASTExpression): - def __init__(self, rooted: bool, isNewTypeId: bool, typ: "ASTType", - initList: Union["ASTParenExprList", "ASTBracedInitList"]) -> None: + def __init__(self, rooted: bool, isNewTypeId: bool, typ: ASTType, + initList: ASTParenExprList | ASTBracedInitList) -> None: self.rooted = rooted self.isNewTypeId = isNewTypeId self.typ = typ @@ -1405,7 +1405,7 @@ class ASTNewExpr(ASTExpression): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: if self.rooted: signode += addnodes.desc_sig_punctuation('::', '::') signode += addnodes.desc_sig_keyword('new', 'new') @@ -1443,7 +1443,7 @@ class ASTDeleteExpr(ASTExpression): return id + self.expr.get_id(version) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: if self.rooted: signode += addnodes.desc_sig_punctuation('::', '::') signode += addnodes.desc_sig_keyword('delete', 'delete') @@ -1458,7 +1458,7 @@ class ASTDeleteExpr(ASTExpression): ################################################################################ class ASTCastExpr(ASTExpression): - def __init__(self, typ: "ASTType", expr: ASTExpression): + def __init__(self, typ: ASTType, expr: ASTExpression): self.typ = typ self.expr = expr @@ -1473,7 +1473,7 @@ class ASTCastExpr(ASTExpression): return 'cv' + self.typ.get_id(version) + self.expr.get_id(version) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_punctuation('(', '(') self.typ.describe_signature(signode, mode, env, symbol) signode += addnodes.desc_sig_punctuation(')', ')') @@ -1507,7 +1507,7 @@ class ASTBinOpExpr(ASTExpression): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: self.exprs[0].describe_signature(signode, mode, env, symbol) for i in range(1, len(self.exprs)): signode += addnodes.desc_sig_space() @@ -1546,7 +1546,7 @@ class ASTConditionalExpr(ASTExpression): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: self.ifExpr.describe_signature(signode, mode, env, symbol) signode += addnodes.desc_sig_space() signode += addnodes.desc_sig_operator('?', '?') @@ -1559,7 +1559,7 @@ class ASTConditionalExpr(ASTExpression): class ASTBracedInitList(ASTBase): - def __init__(self, exprs: list[Union[ASTExpression, "ASTBracedInitList"]], + def __init__(self, exprs: list[ASTExpression | ASTBracedInitList], trailingComma: bool) -> None: self.exprs = exprs self.trailingComma = trailingComma @@ -1568,12 +1568,12 @@ class ASTBracedInitList(ASTBase): return "il%sE" % ''.join(e.get_id(version) for e in self.exprs) def _stringify(self, transform: StringifyTransform) -> str: - exprs = [transform(e) for e in self.exprs] + exprs = ', '.join(transform(e) for e in self.exprs) trailingComma = ',' if self.trailingComma else '' - return '{%s%s}' % (', '.join(exprs), trailingComma) + return f'{{{exprs}{trailingComma}}}' def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) signode += addnodes.desc_sig_punctuation('{', '{') first = True @@ -1614,7 +1614,7 @@ class ASTAssignmentExpr(ASTExpression): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: self.leftExpr.describe_signature(signode, mode, env, symbol) signode += addnodes.desc_sig_space() if ord(self.op[0]) >= ord('a') and ord(self.op[0]) <= ord('z'): @@ -1643,7 +1643,7 @@ class ASTCommaExpr(ASTExpression): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: self.exprs[0].describe_signature(signode, mode, env, symbol) for i in range(1, len(self.exprs)): signode += addnodes.desc_sig_punctuation(',', ',') @@ -1662,7 +1662,7 @@ class ASTFallbackExpr(ASTExpression): return str(self.expr) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += nodes.literal(self.expr, self.expr) @@ -1684,13 +1684,13 @@ class ASTOperator(ASTBase): raise NotImplementedError() def _describe_identifier(self, signode: TextElement, identnode: TextElement, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: """Render the prefix into signode, and the last part into identnode.""" raise NotImplementedError() def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", prefix: str, templateArgs: str, - symbol: "Symbol") -> None: + env: BuildEnvironment, prefix: str, templateArgs: str, + symbol: Symbol) -> None: verify_description_mode(mode) if mode == 'lastIsName': mainName = addnodes.desc_name() @@ -1741,7 +1741,7 @@ class ASTOperatorBuildIn(ASTOperator): return 'operator' + self.op def _describe_identifier(self, signode: TextElement, identnode: TextElement, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_keyword('operator', 'operator') if self.op in ('new', 'new[]', 'delete', 'delete[]') or self.op[0] in "abcnox": signode += addnodes.desc_sig_space() @@ -1762,14 +1762,14 @@ class ASTOperatorLiteral(ASTOperator): return 'operator""' + transform(self.identifier) def _describe_identifier(self, signode: TextElement, identnode: TextElement, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_keyword('operator', 'operator') signode += addnodes.desc_sig_literal_string('""', '""') self.identifier.describe_signature(identnode, 'markType', env, '', '', symbol) class ASTOperatorType(ASTOperator): - def __init__(self, type: "ASTType") -> None: + def __init__(self, type: ASTType) -> None: self.type = type def get_id(self, version: int) -> str: @@ -1785,7 +1785,7 @@ class ASTOperatorType(ASTOperator): return str(self) def _describe_identifier(self, signode: TextElement, identnode: TextElement, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_keyword('operator', 'operator') signode += addnodes.desc_sig_space() self.type.describe_signature(identnode, 'markType', env, symbol) @@ -1806,13 +1806,13 @@ class ASTTemplateArgConstant(ASTBase): return 'X' + self.value.get_id(version) + 'E' def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) self.value.describe_signature(signode, mode, env, symbol) class ASTTemplateArgs(ASTBase): - def __init__(self, args: list[Union["ASTType", ASTTemplateArgConstant]], + def __init__(self, args: list[ASTType | ASTTemplateArgConstant], packExpansion: bool) -> None: assert args is not None self.args = args @@ -1846,7 +1846,7 @@ class ASTTemplateArgs(ASTBase): return '<' + res + '>' def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) signode += addnodes.desc_sig_punctuation('<', '<') first = True @@ -1869,7 +1869,7 @@ class ASTTrailingTypeSpec(ASTBase): raise NotImplementedError(repr(self)) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: raise NotImplementedError(repr(self)) @@ -1903,7 +1903,7 @@ class ASTTrailingTypeSpecFundamental(ASTTrailingTypeSpec): return _id_fundamental_v2[txt] def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: first = True for n in self.names: if not first: @@ -1923,7 +1923,7 @@ class ASTTrailingTypeSpecDecltypeAuto(ASTTrailingTypeSpec): return 'Dc' def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_keyword('decltype', 'decltype') signode += addnodes.desc_sig_punctuation('(', '(') signode += addnodes.desc_sig_keyword('auto', 'auto') @@ -1943,7 +1943,7 @@ class ASTTrailingTypeSpecDecltype(ASTTrailingTypeSpec): return 'DT' + self.expr.get_id(version) + "E" def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_keyword('decltype', 'decltype') signode += addnodes.desc_sig_punctuation('(', '(') self.expr.describe_signature(signode, mode, env, symbol) @@ -1976,7 +1976,7 @@ class ASTTrailingTypeSpecName(ASTTrailingTypeSpec): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: if self.prefix: signode += addnodes.desc_sig_keyword(self.prefix, self.prefix) signode += addnodes.desc_sig_space() @@ -1995,13 +1995,12 @@ class ASTTrailingTypeSpecName(ASTTrailingTypeSpec): class ASTFunctionParameter(ASTBase): - def __init__(self, arg: Union["ASTTypeWithInit", - "ASTTemplateParamConstrainedTypeWithInit"], + def __init__(self, arg: ASTTypeWithInit | ASTTemplateParamConstrainedTypeWithInit, ellipsis: bool = False) -> None: self.arg = arg self.ellipsis = ellipsis - def get_id(self, version: int, objectType: str = None, symbol: "Symbol" = None) -> str: + def get_id(self, version: int, objectType: str = None, symbol: Symbol = None) -> str: # this is not part of the normal name mangling in C++ if symbol: # the anchor will be our parent @@ -2019,7 +2018,7 @@ class ASTFunctionParameter(ASTBase): return transform(self.arg) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) if self.ellipsis: signode += addnodes.desc_sig_punctuation('...', '...') @@ -2037,7 +2036,7 @@ class ASTNoexceptSpec(ASTBase): return 'noexcept' def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_keyword('noexcept', 'noexcept') if self.expr: signode += addnodes.desc_sig_punctuation('(', '(') @@ -2048,7 +2047,7 @@ class ASTNoexceptSpec(ASTBase): class ASTParametersQualifiers(ASTBase): def __init__(self, args: list[ASTFunctionParameter], volatile: bool, const: bool, refQual: str | None, exceptionSpec: ASTNoexceptSpec, - trailingReturn: "ASTType", + trailingReturn: ASTType, override: bool, final: bool, attrs: ASTAttributeList, initializer: str | None) -> None: self.args = args @@ -2128,7 +2127,7 @@ class ASTParametersQualifiers(ASTBase): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) # only use the desc_parameterlist for the outer list, not for inner lists if mode == 'lastIsName': @@ -2199,7 +2198,7 @@ class ASTExplicitSpec(ASTBase): return ''.join(res) def describe_signature(self, signode: TextElement, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_keyword('explicit', 'explicit') if self.expr is not None: signode += addnodes.desc_sig_punctuation('(', '(') @@ -2226,7 +2225,7 @@ class ASTDeclSpecsSimple(ASTBase): self.friend = friend self.attrs = attrs - def mergeWith(self, other: "ASTDeclSpecsSimple") -> "ASTDeclSpecsSimple": + def mergeWith(self, other: ASTDeclSpecsSimple) -> ASTDeclSpecsSimple: if not other: return self return ASTDeclSpecsSimple(self.storage or other.storage, @@ -2271,7 +2270,7 @@ class ASTDeclSpecsSimple(ASTBase): return ' '.join(res) def describe_signature(self, signode: TextElement, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: self.attrs.describe_signature(signode) addSpace = len(self.attrs) != 0 @@ -2355,7 +2354,7 @@ class ASTDeclSpecs(ASTBase): return "".join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) numChildren = len(signode) self.leftSpecs.describe_signature(signode, env, symbol) @@ -2402,7 +2401,7 @@ class ASTArray(ASTBase): return 'A_' def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) signode += addnodes.desc_sig_punctuation('[', '[') if self.size: @@ -2428,7 +2427,7 @@ class ASTDeclarator(ASTBase): raise NotImplementedError(repr(self)) @property - def trailingReturn(self) -> "ASTType": + def trailingReturn(self) -> ASTType: raise NotImplementedError(repr(self)) def require_space_after_declSpecs(self) -> bool: @@ -2450,7 +2449,7 @@ class ASTDeclarator(ASTBase): raise NotImplementedError(repr(self)) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: raise NotImplementedError(repr(self)) @@ -2479,7 +2478,7 @@ class ASTDeclaratorNameParamQual(ASTDeclarator): return self.paramQual.function_params @property - def trailingReturn(self) -> "ASTType": + def trailingReturn(self) -> ASTType: return self.paramQual.trailingReturn # only the modifiers for a function, e.g., @@ -2532,7 +2531,7 @@ class ASTDeclaratorNameParamQual(ASTDeclarator): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) if self.declId: self.declId.describe_signature(signode, mode, env, symbol) @@ -2578,7 +2577,7 @@ class ASTDeclaratorNameBitField(ASTDeclarator): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) if self.declId: self.declId.describe_signature(signode, mode, env, symbol) @@ -2614,7 +2613,7 @@ class ASTDeclaratorPtr(ASTDeclarator): return self.next.function_params @property - def trailingReturn(self) -> "ASTType": + def trailingReturn(self) -> ASTType: return self.next.trailingReturn def require_space_after_declSpecs(self) -> bool: @@ -2675,7 +2674,7 @@ class ASTDeclaratorPtr(ASTDeclarator): return self.next.is_function_type() def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) signode += addnodes.desc_sig_punctuation('*', '*') self.attrs.describe_signature(signode) @@ -2719,7 +2718,7 @@ class ASTDeclaratorRef(ASTDeclarator): return self.next.function_params @property - def trailingReturn(self) -> "ASTType": + def trailingReturn(self) -> ASTType: return self.next.trailingReturn def require_space_after_declSpecs(self) -> bool: @@ -2754,7 +2753,7 @@ class ASTDeclaratorRef(ASTDeclarator): return self.next.is_function_type() def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) signode += addnodes.desc_sig_punctuation('&', '&') self.attrs.describe_signature(signode) @@ -2781,7 +2780,7 @@ class ASTDeclaratorParamPack(ASTDeclarator): return self.next.function_params @property - def trailingReturn(self) -> "ASTType": + def trailingReturn(self) -> ASTType: return self.next.trailingReturn @property @@ -2818,7 +2817,7 @@ class ASTDeclaratorParamPack(ASTDeclarator): return self.next.is_function_type() def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) signode += addnodes.desc_sig_punctuation('...', '...') if self.next.name: @@ -2853,7 +2852,7 @@ class ASTDeclaratorMemPtr(ASTDeclarator): return self.next.function_params @property - def trailingReturn(self) -> "ASTType": + def trailingReturn(self) -> ASTType: return self.next.trailingReturn def require_space_after_declSpecs(self) -> bool: @@ -2910,7 +2909,7 @@ class ASTDeclaratorMemPtr(ASTDeclarator): return self.next.is_function_type() def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) self.className.describe_signature(signode, 'markType', env, symbol) signode += addnodes.desc_sig_punctuation('::', '::') @@ -2954,7 +2953,7 @@ class ASTDeclaratorParen(ASTDeclarator): return self.inner.function_params @property - def trailingReturn(self) -> "ASTType": + def trailingReturn(self) -> ASTType: return self.inner.trailingReturn def require_space_after_declSpecs(self) -> bool: @@ -2992,7 +2991,7 @@ class ASTDeclaratorParen(ASTDeclarator): return self.inner.is_function_type() def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) signode += addnodes.desc_sig_punctuation('(', '(') self.inner.describe_signature(signode, mode, env, symbol) @@ -3015,7 +3014,7 @@ class ASTPackExpansionExpr(ASTExpression): return 'sp' + id def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: self.expr.describe_signature(signode, mode, env, symbol) signode += addnodes.desc_sig_punctuation('...', '...') @@ -3032,7 +3031,7 @@ class ASTParenExprList(ASTBaseParenExprList): return '(%s)' % ', '.join(exprs) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) signode += addnodes.desc_sig_punctuation('(', '(') first = True @@ -3060,7 +3059,7 @@ class ASTInitializer(ASTBase): return val def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) if self.hasAssign: signode += addnodes.desc_sig_space() @@ -3093,11 +3092,11 @@ class ASTType(ASTBase): return self.decl.function_params @property - def trailingReturn(self) -> "ASTType": + def trailingReturn(self) -> ASTType: return self.decl.trailingReturn def get_id(self, version: int, objectType: str = None, - symbol: "Symbol" = None) -> str: + symbol: Symbol = None) -> str: if version == 1: res = [] if objectType: # needs the name @@ -3166,7 +3165,7 @@ class ASTType(ASTBase): return 'type' def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) self.declSpecs.describe_signature(signode, 'markType', env, symbol) if (self.decl.require_space_after_declSpecs() and @@ -3193,7 +3192,7 @@ class ASTTemplateParamConstrainedTypeWithInit(ASTBase): def isPack(self) -> bool: return self.type.isPack - def get_id(self, version: int, objectType: str = None, symbol: "Symbol" = None) -> str: + def get_id(self, version: int, objectType: str = None, symbol: Symbol = None) -> str: # this is not part of the normal name mangling in C++ assert version >= 2 if symbol: @@ -3210,7 +3209,7 @@ class ASTTemplateParamConstrainedTypeWithInit(ASTBase): return res def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: self.type.describe_signature(signode, mode, env, symbol) if self.init: signode += addnodes.desc_sig_space() @@ -3233,7 +3232,7 @@ class ASTTypeWithInit(ASTBase): return self.type.isPack def get_id(self, version: int, objectType: str = None, - symbol: "Symbol" = None) -> str: + symbol: Symbol = None) -> str: if objectType != 'member': return self.type.get_id(version, objectType) if version == 1: @@ -3249,7 +3248,7 @@ class ASTTypeWithInit(ASTBase): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) self.type.describe_signature(signode, mode, env, symbol) if self.init: @@ -3262,7 +3261,7 @@ class ASTTypeUsing(ASTBase): self.type = type def get_id(self, version: int, objectType: str = None, - symbol: "Symbol" = None) -> str: + symbol: Symbol = None) -> str: if version == 1: raise NoOldIdError() return symbol.get_full_nested_name().get_id(version) @@ -3279,7 +3278,7 @@ class ASTTypeUsing(ASTBase): return 'using' def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) self.name.describe_signature(signode, mode, env, symbol=symbol) if self.type: @@ -3302,7 +3301,7 @@ class ASTConcept(ASTBase): return self.nestedName def get_id(self, version: int, objectType: str = None, - symbol: "Symbol" = None) -> str: + symbol: Symbol = None) -> str: if version == 1: raise NoOldIdError() return symbol.get_full_nested_name().get_id(version) @@ -3314,7 +3313,7 @@ class ASTConcept(ASTBase): return res def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: self.nestedName.describe_signature(signode, mode, env, symbol) if self.initializer: self.initializer.describe_signature(signode, mode, env, symbol) @@ -3341,7 +3340,7 @@ class ASTBaseClass(ASTBase): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) if self.visibility is not None: signode += addnodes.desc_sig_keyword(self.visibility, @@ -3363,7 +3362,7 @@ class ASTClass(ASTBase): self.bases = bases self.attrs = attrs - def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str: + def get_id(self, version: int, objectType: str, symbol: Symbol) -> str: return symbol.get_full_nested_name().get_id(version) def _stringify(self, transform: StringifyTransform) -> str: @@ -3385,7 +3384,7 @@ class ASTClass(ASTBase): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) self.attrs.describe_signature(signode) if len(self.attrs) != 0: @@ -3411,7 +3410,7 @@ class ASTUnion(ASTBase): self.name = name self.attrs = attrs - def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str: + def get_id(self, version: int, objectType: str, symbol: Symbol) -> str: if version == 1: raise NoOldIdError() return symbol.get_full_nested_name().get_id(version) @@ -3425,7 +3424,7 @@ class ASTUnion(ASTBase): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) self.attrs.describe_signature(signode) if len(self.attrs) != 0: @@ -3441,7 +3440,7 @@ class ASTEnum(ASTBase): self.underlyingType = underlyingType self.attrs = attrs - def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str: + def get_id(self, version: int, objectType: str, symbol: Symbol) -> str: if version == 1: raise NoOldIdError() return symbol.get_full_nested_name().get_id(version) @@ -3461,7 +3460,7 @@ class ASTEnum(ASTBase): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) # self.scoped has been done by the CPPEnumObject self.attrs.describe_signature(signode) @@ -3483,7 +3482,7 @@ class ASTEnumerator(ASTBase): self.init = init self.attrs = attrs - def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str: + def get_id(self, version: int, objectType: str, symbol: Symbol) -> str: if version == 1: raise NoOldIdError() return symbol.get_full_nested_name().get_id(version) @@ -3499,7 +3498,7 @@ class ASTEnumerator(ASTBase): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: verify_description_mode(mode) self.name.describe_signature(signode, mode, env, symbol) if len(self.attrs) != 0: @@ -3524,7 +3523,7 @@ class ASTTemplateParam(ASTBase): raise NotImplementedError(repr(self)) def describe_signature(self, parentNode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: raise NotImplementedError(repr(self)) @property @@ -3576,7 +3575,7 @@ class ASTTemplateKeyParamPackIdDefault(ASTTemplateParam): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_keyword(self.key, self.key) if self.parameterPack: if self.identifier: @@ -3610,7 +3609,7 @@ class ASTTemplateParamType(ASTTemplateParam): def get_identifier(self) -> ASTIdentifier: return self.data.get_identifier() - def get_id(self, version: int, objectType: str = None, symbol: "Symbol" = None) -> str: + def get_id(self, version: int, objectType: str = None, symbol: Symbol = None) -> str: # this is not part of the normal name mangling in C++ assert version >= 2 if symbol: @@ -3623,12 +3622,12 @@ class ASTTemplateParamType(ASTTemplateParam): return transform(self.data) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: self.data.describe_signature(signode, mode, env, symbol) class ASTTemplateParamTemplateType(ASTTemplateParam): - def __init__(self, nestedParams: "ASTTemplateParams", + def __init__(self, nestedParams: ASTTemplateParams, data: ASTTemplateKeyParamPackIdDefault) -> None: assert nestedParams assert data @@ -3648,7 +3647,7 @@ class ASTTemplateParamTemplateType(ASTTemplateParam): return self.data.get_identifier() def get_id( - self, version: int, objectType: str | None = None, symbol: Optional["Symbol"] = None + self, version: int, objectType: str | None = None, symbol: Symbol | None = None ) -> str: assert version >= 2 # this is not part of the normal name mangling in C++ @@ -3662,7 +3661,7 @@ class ASTTemplateParamTemplateType(ASTTemplateParam): return transform(self.nestedParams) + transform(self.data) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: self.nestedParams.describe_signature(signode, 'noneIsName', env, symbol) signode += addnodes.desc_sig_space() self.data.describe_signature(signode, mode, env, symbol) @@ -3697,7 +3696,7 @@ class ASTTemplateParamNonType(ASTTemplateParam): else: return None - def get_id(self, version: int, objectType: str = None, symbol: "Symbol" = None) -> str: + def get_id(self, version: int, objectType: str = None, symbol: Symbol = None) -> str: assert version >= 2 # this is not part of the normal name mangling in C++ if symbol: @@ -3716,7 +3715,7 @@ class ASTTemplateParamNonType(ASTTemplateParam): return res def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: self.param.describe_signature(signode, mode, env, symbol) if self.parameterPack: signode += addnodes.desc_sig_punctuation('...', '...') @@ -3724,7 +3723,7 @@ class ASTTemplateParamNonType(ASTTemplateParam): class ASTTemplateParams(ASTBase): def __init__(self, params: list[ASTTemplateParam], - requiresClause: Optional["ASTRequiresClause"]) -> None: + requiresClause: ASTRequiresClause | None) -> None: assert params is not None self.params = params self.requiresClause = requiresClause @@ -3753,7 +3752,7 @@ class ASTTemplateParams(ASTBase): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_keyword('template', 'template') signode += addnodes.desc_sig_punctuation('<', '<') first = True @@ -3769,8 +3768,8 @@ class ASTTemplateParams(ASTBase): self.requiresClause.describe_signature(signode, mode, env, symbol) def describe_signature_as_introducer( - self, parentNode: desc_signature, mode: str, env: "BuildEnvironment", - symbol: "Symbol", lineSpec: bool) -> None: + self, parentNode: desc_signature, mode: str, env: BuildEnvironment, + symbol: Symbol, lineSpec: bool) -> None: def makeLine(parentNode: desc_signature) -> addnodes.desc_signature_line: signode = addnodes.desc_signature_line() parentNode += signode @@ -3818,7 +3817,7 @@ class ASTTemplateIntroductionParameter(ASTBase): def get_identifier(self) -> ASTIdentifier: return self.identifier - def get_id(self, version: int, objectType: str = None, symbol: "Symbol" = None) -> str: + def get_id(self, version: int, objectType: str = None, symbol: Symbol = None) -> str: assert version >= 2 # this is not part of the normal name mangling in C++ if symbol: @@ -3847,7 +3846,7 @@ class ASTTemplateIntroductionParameter(ASTBase): return ''.join(res) def describe_signature(self, signode: TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: if self.parameterPack: signode += addnodes.desc_sig_punctuation('...', '...') self.identifier.describe_signature(signode, mode, env, '', '', symbol) @@ -3888,7 +3887,7 @@ class ASTTemplateIntroduction(ASTBase): def describe_signature_as_introducer( self, parentNode: desc_signature, mode: str, - env: "BuildEnvironment", symbol: "Symbol", lineSpec: bool) -> None: + env: BuildEnvironment, symbol: Symbol, lineSpec: bool) -> None: # Note: 'lineSpec' has no effect on template introductions. signode = addnodes.desc_signature_line() parentNode += signode @@ -3913,7 +3912,7 @@ class ASTTemplateDeclarationPrefix(ASTBase): # templates is None means it's an explicit instantiation of a variable self.templates = templates - def get_requires_clause_in_last(self) -> Optional["ASTRequiresClause"]: + def get_requires_clause_in_last(self) -> ASTRequiresClause | None: if self.templates is None: return None lastList = self.templates[-1] @@ -3940,7 +3939,7 @@ class ASTTemplateDeclarationPrefix(ASTBase): return ''.join(res) def describe_signature(self, signode: desc_signature, mode: str, - env: "BuildEnvironment", symbol: "Symbol", lineSpec: bool) -> None: + env: BuildEnvironment, symbol: Symbol, lineSpec: bool) -> None: verify_description_mode(mode) for t in self.templates: t.describe_signature_as_introducer(signode, 'lastIsName', env, symbol, lineSpec) @@ -3954,7 +3953,7 @@ class ASTRequiresClause(ASTBase): return 'requires ' + transform(self.expr) def describe_signature(self, signode: nodes.TextElement, mode: str, - env: "BuildEnvironment", symbol: "Symbol") -> None: + env: BuildEnvironment, symbol: Symbol) -> None: signode += addnodes.desc_sig_keyword('requires', 'requires') signode += addnodes.desc_sig_space() self.expr.describe_signature(signode, mode, env, symbol) @@ -3982,7 +3981,7 @@ class ASTDeclaration(ASTBase): # set by CPPObject._add_enumerator_to_parent self.enumeratorScopedSymbol: Symbol = None - def clone(self) -> "ASTDeclaration": + def clone(self) -> ASTDeclaration: templatePrefixClone = self.templatePrefix.clone() if self.templatePrefix else None trailingRequiresClasueClone = self.trailingRequiresClause.clone() \ if self.trailingRequiresClause else None @@ -4065,7 +4064,7 @@ class ASTDeclaration(ASTBase): return ''.join(res) def describe_signature(self, signode: desc_signature, mode: str, - env: "BuildEnvironment", options: dict) -> None: + env: BuildEnvironment, options: dict) -> None: verify_description_mode(mode) assert self.symbol # The caller of the domain added a desc_signature node. @@ -4146,7 +4145,7 @@ class ASTNamespace(ASTBase): class SymbolLookupResult: - def __init__(self, symbols: Iterator["Symbol"], parentSymbol: "Symbol", + def __init__(self, symbols: Iterator[Symbol], parentSymbol: Symbol, identOrOp: ASTIdentifier | ASTOperator, templateParams: Any, templateArgs: ASTTemplateArgs) -> None: self.symbols = symbols @@ -4227,7 +4226,7 @@ class Symbol: else: return super().__setattr__(key, value) - def __init__(self, parent: Optional["Symbol"], + def __init__(self, parent: Symbol | None, identOrOp: ASTIdentifier | ASTOperator | None, templateParams: ASTTemplateParams | ASTTemplateIntroduction | None, templateArgs: Any, declaration: ASTDeclaration | None, @@ -4349,7 +4348,7 @@ class Symbol: yield from sChild.get_all_symbols() @property - def children_recurse_anon(self) -> Generator["Symbol", None, None]: + def children_recurse_anon(self) -> Generator[Symbol, None, None]: for c in self._children: yield c if not c.identOrOp.is_anon(): @@ -4357,7 +4356,7 @@ class Symbol: yield from c.children_recurse_anon - def get_lookup_key(self) -> "LookupKey": + def get_lookup_key(self) -> LookupKey: # The pickle files for the environment and for each document are distinct. # The environment has all the symbols, but the documents has xrefs that # must know their scope. A lookup key is essentially a specification of @@ -4395,7 +4394,7 @@ class Symbol: templateParams: Any, templateArgs: ASTTemplateArgs, templateShorthand: bool, matchSelf: bool, recurseInAnon: bool, correctPrimaryTemplateArgs: bool - ) -> "Symbol": + ) -> Symbol: if Symbol.debug_lookup: Symbol.debug_print("_find_first_named_symbol ->") res = self._find_named_symbols(identOrOp, templateParams, templateArgs, @@ -4411,7 +4410,7 @@ class Symbol: templateParams: Any, templateArgs: ASTTemplateArgs, templateShorthand: bool, matchSelf: bool, recurseInAnon: bool, correctPrimaryTemplateArgs: bool, - searchInSiblings: bool) -> Iterator["Symbol"]: + searchInSiblings: bool) -> Iterator[Symbol]: if Symbol.debug_lookup: Symbol.debug_indent += 1 Symbol.debug_print("_find_named_symbols:") @@ -4435,7 +4434,7 @@ class Symbol: if not _is_specialization(templateParams, templateArgs): templateArgs = None - def matches(s: "Symbol") -> bool: + def matches(s: Symbol) -> bool: if s.identOrOp != identOrOp: return False if (s.templateParams is None) != (templateParams is None): @@ -4497,7 +4496,7 @@ class Symbol: nestedName: ASTNestedName, templateDecls: list[Any], onMissingQualifiedSymbol: Callable[ - ["Symbol", ASTIdentifier | ASTOperator, Any, ASTTemplateArgs], "Symbol" + [Symbol, ASTIdentifier | ASTOperator, Any, ASTTemplateArgs], Symbol ], strictTemplateParamArgLists: bool, ancestorLookupType: str, templateShorthand: bool, matchSelf: bool, @@ -4628,7 +4627,7 @@ class Symbol: identOrOp, templateParams, templateArgs) def _add_symbols(self, nestedName: ASTNestedName, templateDecls: list[Any], - declaration: ASTDeclaration, docname: str, line: int) -> "Symbol": + declaration: ASTDeclaration, docname: str, line: int) -> Symbol: # Used for adding a whole path of symbols, where the last may or may not # be an actual declaration. @@ -4641,10 +4640,10 @@ class Symbol: Symbol.debug_print("decl: ", declaration) Symbol.debug_print(f"location: {docname}:{line}") - def onMissingQualifiedSymbol(parentSymbol: "Symbol", + def onMissingQualifiedSymbol(parentSymbol: Symbol, identOrOp: ASTIdentifier | ASTOperator, templateParams: Any, templateArgs: ASTTemplateArgs - ) -> "Symbol": + ) -> Symbol: if Symbol.debug_lookup: Symbol.debug_indent += 1 Symbol.debug_print("_add_symbols, onMissingQualifiedSymbol:") @@ -4725,7 +4724,7 @@ class Symbol: # First check if one of those with a declaration matches. # If it's a function, we need to compare IDs, # otherwise there should be only one symbol with a declaration. - def makeCandSymbol() -> "Symbol": + def makeCandSymbol() -> Symbol: if Symbol.debug_lookup: Symbol.debug_print("begin: creating candidate symbol") symbol = Symbol(parent=lookupResult.parentSymbol, @@ -4742,7 +4741,7 @@ class Symbol: else: candSymbol = makeCandSymbol() - def handleDuplicateDeclaration(symbol: "Symbol", candSymbol: "Symbol") -> None: + def handleDuplicateDeclaration(symbol: Symbol, candSymbol: Symbol) -> None: if Symbol.debug_lookup: Symbol.debug_indent += 1 Symbol.debug_print("redeclaration") @@ -4811,8 +4810,8 @@ class Symbol: symbol._fill_empty(declaration, docname, line) return symbol - def merge_with(self, other: "Symbol", docnames: list[str], - env: "BuildEnvironment") -> None: + def merge_with(self, other: Symbol, docnames: list[str], + env: BuildEnvironment) -> None: if Symbol.debug_lookup: Symbol.debug_indent += 1 Symbol.debug_print("merge_with:") @@ -4919,7 +4918,7 @@ class Symbol: Symbol.debug_indent -= 2 def add_name(self, nestedName: ASTNestedName, - templatePrefix: ASTTemplateDeclarationPrefix = None) -> "Symbol": + templatePrefix: ASTTemplateDeclarationPrefix = None) -> Symbol: if Symbol.debug_lookup: Symbol.debug_indent += 1 Symbol.debug_print("add_name:") @@ -4934,7 +4933,7 @@ class Symbol: return res def add_declaration(self, declaration: ASTDeclaration, - docname: str, line: int) -> "Symbol": + docname: str, line: int) -> Symbol: if Symbol.debug_lookup: Symbol.debug_indent += 1 Symbol.debug_print("add_declaration:") @@ -4953,7 +4952,7 @@ class Symbol: def find_identifier(self, identOrOp: ASTIdentifier | ASTOperator, matchSelf: bool, recurseInAnon: bool, searchInSiblings: bool - ) -> "Symbol": + ) -> Symbol: if Symbol.debug_lookup: Symbol.debug_indent += 1 Symbol.debug_print("find_identifier:") @@ -4982,7 +4981,7 @@ class Symbol: current = current.siblingAbove return None - def direct_lookup(self, key: "LookupKey") -> "Symbol": + def direct_lookup(self, key: LookupKey) -> Symbol: if Symbol.debug_lookup: Symbol.debug_indent += 1 Symbol.debug_print("direct_lookup:") @@ -5025,7 +5024,7 @@ class Symbol: def find_name(self, nestedName: ASTNestedName, templateDecls: list[Any], typ: str, templateShorthand: bool, matchSelf: bool, - recurseInAnon: bool, searchInSiblings: bool) -> tuple[list["Symbol"], str]: + recurseInAnon: bool, searchInSiblings: bool) -> tuple[list[Symbol], str]: # templateShorthand: missing template parameter lists for templates is ok # If the first component is None, # then the second component _may_ be a string explaining why. @@ -5046,10 +5045,10 @@ class Symbol: class QualifiedSymbolIsTemplateParam(Exception): pass - def onMissingQualifiedSymbol(parentSymbol: "Symbol", + def onMissingQualifiedSymbol(parentSymbol: Symbol, identOrOp: ASTIdentifier | ASTOperator, templateParams: Any, - templateArgs: ASTTemplateArgs) -> "Symbol": + templateArgs: ASTTemplateArgs) -> Symbol: # TODO: Maybe search without template args? # Though, the correctPrimaryTemplateArgs does # that for primary templates. @@ -5101,7 +5100,7 @@ class Symbol: return None, None def find_declaration(self, declaration: ASTDeclaration, typ: str, templateShorthand: bool, - matchSelf: bool, recurseInAnon: bool) -> "Symbol": + matchSelf: bool, recurseInAnon: bool) -> Symbol: # templateShorthand: missing template parameter lists for templates is ok if Symbol.debug_lookup: Symbol.debug_indent += 1 @@ -5112,10 +5111,10 @@ class Symbol: else: templateDecls = [] - def onMissingQualifiedSymbol(parentSymbol: "Symbol", + def onMissingQualifiedSymbol(parentSymbol: Symbol, identOrOp: ASTIdentifier | ASTOperator, templateParams: Any, - templateArgs: ASTTemplateArgs) -> "Symbol": + templateArgs: ASTTemplateArgs) -> Symbol: return None lookupResult = self._symbol_lookup(nestedName, templateDecls, @@ -5389,7 +5388,7 @@ class DefinitionParser(BaseParser): if self.skip_string(close): break if not self.skip_string_and_ws(','): - self.fail("Error in %s, expected ',' or '%s'." % (name, close)) + self.fail(f"Error in {name}, expected ',' or '{close}'.") if self.current_char == close and close == '}': self.pos += 1 trailingComma = True @@ -6061,12 +6060,12 @@ class DefinitionParser(BaseParser): if signedness is not None: self.fail(f"Can not have both {typ} and {signedness}.") if len(width) != 0: - self.fail("Can not have both {} and {}.".format(typ, ' '.join(width))) + self.fail(f"Can not have both {typ} and {' '.join(width)}.") elif typ == 'char': if modifier is not None: self.fail(f"Can not have both {typ} and {modifier}.") if len(width) != 0: - self.fail("Can not have both {} and {}.".format(typ, ' '.join(width))) + self.fail(f"Can not have both {typ} and {' '.join(width)}.") elif typ == 'int': if modifier is not None: self.fail(f"Can not have both {typ} and {modifier}.") @@ -6074,19 +6073,19 @@ class DefinitionParser(BaseParser): if modifier is not None: self.fail(f"Can not have both {typ} and {modifier}.") if len(width) != 0: - self.fail("Can not have both {} and {}.".format(typ, ' '.join(width))) + self.fail(f"Can not have both {typ} and {' '.join(width)}.") elif typ == 'float': if signedness is not None: self.fail(f"Can not have both {typ} and {signedness}.") if len(width) != 0: - self.fail("Can not have both {} and {}.".format(typ, ' '.join(width))) + self.fail(f"Can not have both {typ} and {' '.join(width)}.") elif typ == 'double': if signedness is not None: self.fail(f"Can not have both {typ} and {signedness}.") if len(width) > 1: - self.fail("Can not have both {} and {}.".format(typ, ' '.join(width))) + self.fail(f"Can not have both {typ} and {' '.join(width)}.") if len(width) == 1 and width[0] != 'long': - self.fail("Can not have both {} and {}.".format(typ, ' '.join(width))) + self.fail(f"Can not have both {typ} and {' '.join(width)}.") elif typ is None: if modifier is not None: self.fail(f"Can not have {modifier} without a floating point type.") @@ -7334,12 +7333,10 @@ class CPPObject(ObjectDescription[ASTDeclaration]): parentSymbol = env.temp_data['cpp:parent_symbol'] parentDecl = parentSymbol.declaration if parentDecl is not None and parentDecl.objectType == 'function': - msg = "C++ declarations inside functions are not supported." \ - " Parent function: {}\nDirective name: {}\nDirective arg: {}" - logger.warning(msg.format( - str(parentSymbol.get_full_nested_name()), - self.name, self.arguments[0] - ), location=self.get_location()) + msg = ("C++ declarations inside functions are not supported. " + f"Parent function: {parentSymbol.get_full_nested_name()}\n" + f"Directive name: {self.name}\nDirective arg: {self.arguments[0]}") + logger.warning(msg, location=self.get_location()) name = _make_phony_error_name() symbol = parentSymbol.add_name(name) env.temp_data['cpp:last_symbol'] = symbol @@ -7557,7 +7554,7 @@ class CPPNamespacePopObject(SphinxDirective): class AliasNode(nodes.Element): def __init__(self, sig: str, aliasOptions: dict, - env: "BuildEnvironment" = None, + env: BuildEnvironment = None, parentKey: LookupKey = None) -> None: super().__init__() self.sig = sig @@ -7572,7 +7569,7 @@ class AliasNode(nodes.Element): assert parentKey is not None self.parentKey = parentKey - def copy(self) -> 'AliasNode': + def copy(self) -> AliasNode: return self.__class__(self.sig, self.aliasOptions, env=None, parentKey=self.parentKey) @@ -8032,7 +8029,7 @@ class CPPDomain(Domain): objtypes = self.objtypes_for_role(typ) if objtypes: return declTyp in objtypes - print("Type is %s, declaration type is %s" % (typ, declTyp)) + print(f"Type is {typ}, declaration type is {declTyp}") raise AssertionError() if not checkType(): logger.warning("cpp:%s targets a %s (%s).", diff --git a/sphinx/domains/index.py b/sphinx/domains/index.py index 70965ead2..a4dac8428 100644 --- a/sphinx/domains/index.py +++ b/sphinx/domains/index.py @@ -109,7 +109,7 @@ class IndexRole(ReferenceRole): return [index, target, text], [] -def setup(app: "Sphinx") -> dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_domain(IndexDomain) app.add_directive('index', IndexDirective) app.add_role('index', IndexRole()) diff --git a/sphinx/domains/math.py b/sphinx/domains/math.py index 9ca3eb030..410cb3142 100644 --- a/sphinx/domains/math.py +++ b/sphinx/domains/math.py @@ -89,7 +89,7 @@ class MathDomain(Domain): for docname in docnames: self.data['has_equations'][docname] = otherdata['has_equations'][docname] - def resolve_xref(self, env: BuildEnvironment, fromdocname: str, builder: "Builder", + def resolve_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder, typ: str, target: str, node: pending_xref, contnode: Element ) -> Element | None: assert typ in ('eq', 'numref') @@ -118,7 +118,7 @@ class MathDomain(Domain): else: return None - def resolve_any_xref(self, env: BuildEnvironment, fromdocname: str, builder: "Builder", + def resolve_any_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder, target: str, node: pending_xref, contnode: Element ) -> list[tuple[str, Element]]: refnode = self.resolve_xref(env, fromdocname, builder, 'eq', target, node, contnode) @@ -137,7 +137,7 @@ class MathDomain(Domain): return any(self.data['has_equations'].values()) -def setup(app: "Sphinx") -> dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_domain(MathDomain) app.add_role('eq', MathReferenceRole(warn_dangling=True)) diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py index 3f43f3783..e43f72b5a 100644 --- a/sphinx/domains/python.py +++ b/sphinx/domains/python.py @@ -128,7 +128,7 @@ def _parse_annotation(annotation: str, env: BuildEnvironment) -> list[Node]: """Parse type annotation.""" def unparse(node: ast.AST) -> list[Node]: if isinstance(node, ast.Attribute): - return [nodes.Text("%s.%s" % (unparse(node.value)[0], node.attr))] + return [nodes.Text(f"{unparse(node.value)[0]}.{node.attr}")] elif isinstance(node, ast.BinOp): result: list[Node] = unparse(node.left) result.extend(unparse(node.op)) @@ -685,7 +685,7 @@ class PyFunction(PyObject): text = _('%s() (in module %s)') % (name, modname) self.indexnode['entries'].append(('single', text, node_id, '', None)) else: - text = '%s; %s()' % (pairindextypes['builtin'], name) + text = f'{pairindextypes["builtin"]}; {name}()' self.indexnode['entries'].append(('pair', text, node_id, '', None)) def get_index_text(self, modname: str, name_cls: tuple[str, str]) -> str: @@ -1015,7 +1015,7 @@ class PyModule(SphinxDirective): # the platform and synopsis aren't printed; in fact, they are only # used in the modindex currently ret.append(target) - indextext = '%s; %s' % (pairindextypes['module'], modname) + indextext = f'{pairindextypes["module"]}; {modname}' inode = addnodes.index(entries=[('pair', indextext, node_id, '', None)]) ret.append(inode) ret.extend(content_node.children) diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py index 165ef7d95..2d98f476c 100644 --- a/sphinx/domains/std.py +++ b/sphinx/domains/std.py @@ -42,7 +42,7 @@ class GenericObject(ObjectDescription[str]): A generic x-ref directive registered with Sphinx.add_object_type(). """ indextemplate: str = '' - parse_node: Callable[["BuildEnvironment", str, desc_signature], str] = None + parse_node: Callable[[BuildEnvironment, str, desc_signature], str] = None def handle_signature(self, sig: str, signode: desc_signature) -> str: if self.parse_node: @@ -90,7 +90,7 @@ class EnvVarXRefRole(XRefRole): Cross-referencing role for environment variables (adds an index entry). """ - def result_nodes(self, document: nodes.document, env: "BuildEnvironment", node: Element, + def result_nodes(self, document: nodes.document, env: BuildEnvironment, node: Element, is_ref: bool) -> tuple[list[Node], list[system_message]]: if not is_ref: return [node], [] @@ -279,7 +279,7 @@ class Program(SphinxDirective): class OptionXRefRole(XRefRole): - def process_link(self, env: "BuildEnvironment", refnode: Element, has_explicit_title: bool, + def process_link(self, env: BuildEnvironment, refnode: Element, has_explicit_title: bool, title: str, target: str) -> tuple[str, str]: refnode['std:program'] = env.ref_context.get('std:program') return title, target @@ -291,7 +291,7 @@ def split_term_classifiers(line: str) -> list[str | None]: return parts -def make_glossary_term(env: "BuildEnvironment", textnodes: Iterable[Node], index_key: str, +def make_glossary_term(env: BuildEnvironment, textnodes: Iterable[Node], index_key: str, source: str, lineno: int, node_id: str, document: nodes.document ) -> nodes.term: # get a text-only representation of the term and register it @@ -508,7 +508,7 @@ class ProductionList(SphinxDirective): self.state.document.note_implicit_target(subnode, subnode) if len(productionGroup) != 0: - objName = "%s:%s" % (productionGroup, name) + objName = f"{productionGroup}:{name}" else: objName = name domain.note_object('token', objName, node_id, location=node) @@ -526,7 +526,7 @@ class ProductionList(SphinxDirective): class TokenXRefRole(XRefRole): - def process_link(self, env: "BuildEnvironment", refnode: Element, has_explicit_title: bool, + def process_link(self, env: BuildEnvironment, refnode: Element, has_explicit_title: bool, title: str, target: str) -> tuple[str, str]: target = target.lstrip('~') # a title-specific thing if not self.has_explicit_title and title[0] == '~': @@ -620,7 +620,7 @@ class StandardDomain(Domain): nodes.container: ('code-block', None), } - def __init__(self, env: "BuildEnvironment") -> None: + def __init__(self, env: BuildEnvironment) -> None: super().__init__(env) # set up enumerable nodes @@ -731,7 +731,7 @@ class StandardDomain(Domain): self.anonlabels[key] = data def process_doc( - self, env: "BuildEnvironment", docname: str, document: nodes.document + self, env: BuildEnvironment, docname: str, document: nodes.document ) -> None: for name, explicit in document.nametypes.items(): if not explicit: @@ -787,7 +787,7 @@ class StandardDomain(Domain): if (program, name) not in self.progoptions: self.progoptions[program, name] = (docname, labelid) - def build_reference_node(self, fromdocname: str, builder: "Builder", docname: str, + def build_reference_node(self, fromdocname: str, builder: Builder, docname: str, labelid: str, sectname: str, rolename: str, **options: Any ) -> Element: nodeclass = options.pop('nodeclass', nodes.reference) @@ -812,7 +812,7 @@ class StandardDomain(Domain): newnode.append(innernode) return newnode - def resolve_xref(self, env: "BuildEnvironment", fromdocname: str, builder: "Builder", + def resolve_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder, typ: str, target: str, node: pending_xref, contnode: Element ) -> Element | None: if typ == 'ref': @@ -832,8 +832,8 @@ class StandardDomain(Domain): return resolver(env, fromdocname, builder, typ, target, node, contnode) - def _resolve_ref_xref(self, env: "BuildEnvironment", fromdocname: str, - builder: "Builder", typ: str, target: str, node: pending_xref, + def _resolve_ref_xref(self, env: BuildEnvironment, fromdocname: str, + builder: Builder, typ: str, target: str, node: pending_xref, contnode: Element) -> Element | None: if node['refexplicit']: # reference to anonymous label; the reference uses @@ -850,8 +850,8 @@ class StandardDomain(Domain): return self.build_reference_node(fromdocname, builder, docname, labelid, sectname, 'ref') - def _resolve_numref_xref(self, env: "BuildEnvironment", fromdocname: str, - builder: "Builder", typ: str, target: str, + def _resolve_numref_xref(self, env: BuildEnvironment, fromdocname: str, + builder: Builder, typ: str, target: str, node: pending_xref, contnode: Element) -> Element | None: if target in self.labels: docname, labelid, figname = self.labels.get(target, ('', '', '')) @@ -913,8 +913,8 @@ class StandardDomain(Domain): nodeclass=addnodes.number_reference, title=title) - def _resolve_keyword_xref(self, env: "BuildEnvironment", fromdocname: str, - builder: "Builder", typ: str, target: str, + def _resolve_keyword_xref(self, env: BuildEnvironment, fromdocname: str, + builder: Builder, typ: str, target: str, node: pending_xref, contnode: Element) -> Element | None: # keywords are oddballs: they are referenced by named labels docname, labelid, _ = self.labels.get(target, ('', '', '')) @@ -923,8 +923,8 @@ class StandardDomain(Domain): return make_refnode(builder, fromdocname, docname, labelid, contnode) - def _resolve_doc_xref(self, env: "BuildEnvironment", fromdocname: str, - builder: "Builder", typ: str, target: str, + def _resolve_doc_xref(self, env: BuildEnvironment, fromdocname: str, + builder: Builder, typ: str, target: str, node: pending_xref, contnode: Element) -> Element | None: # directly reference to document by source name; can be absolute or relative refdoc = node.get('refdoc', fromdocname) @@ -940,8 +940,8 @@ class StandardDomain(Domain): innernode = nodes.inline(caption, caption, classes=['doc']) return make_refnode(builder, fromdocname, docname, None, innernode) - def _resolve_option_xref(self, env: "BuildEnvironment", fromdocname: str, - builder: "Builder", typ: str, target: str, + def _resolve_option_xref(self, env: BuildEnvironment, fromdocname: str, + builder: Builder, typ: str, target: str, node: pending_xref, contnode: Element) -> Element | None: progname = node.get('std:program') target = target.strip() @@ -973,8 +973,8 @@ class StandardDomain(Domain): return make_refnode(builder, fromdocname, docname, labelid, contnode) - def _resolve_term_xref(self, env: "BuildEnvironment", fromdocname: str, - builder: "Builder", typ: str, target: str, + def _resolve_term_xref(self, env: BuildEnvironment, fromdocname: str, + builder: Builder, typ: str, target: str, node: pending_xref, contnode: Element) -> Element: result = self._resolve_obj_xref(env, fromdocname, builder, typ, target, node, contnode) @@ -988,8 +988,8 @@ class StandardDomain(Domain): else: return None - def _resolve_obj_xref(self, env: "BuildEnvironment", fromdocname: str, - builder: "Builder", typ: str, target: str, + def _resolve_obj_xref(self, env: BuildEnvironment, fromdocname: str, + builder: Builder, typ: str, target: str, node: pending_xref, contnode: Element) -> Element | None: objtypes = self.objtypes_for_role(typ) or [] for objtype in objtypes: @@ -1003,8 +1003,8 @@ class StandardDomain(Domain): return make_refnode(builder, fromdocname, docname, labelid, contnode) - def resolve_any_xref(self, env: "BuildEnvironment", fromdocname: str, - builder: "Builder", target: str, node: pending_xref, + def resolve_any_xref(self, env: BuildEnvironment, fromdocname: str, + builder: Builder, target: str, node: pending_xref, contnode: Element) -> list[tuple[str, Element]]: results: list[tuple[str, Element]] = [] ltarget = target.lower() # :ref: lowercases its target automatically @@ -1084,7 +1084,7 @@ class StandardDomain(Domain): figtype, _ = self.enumerable_nodes.get(node.__class__, (None, None)) return figtype - def get_fignumber(self, env: "BuildEnvironment", builder: "Builder", + def get_fignumber(self, env: BuildEnvironment, builder: Builder, figtype: str, docname: str, target_node: Element) -> tuple[int, ...]: if figtype == 'section': if builder.name == 'latex': @@ -1122,7 +1122,7 @@ class StandardDomain(Domain): return None -def warn_missing_reference(app: "Sphinx", domain: Domain, node: pending_xref +def warn_missing_reference(app: Sphinx, domain: Domain, node: pending_xref ) -> bool | None: if (domain and domain.name != 'std') or node['reftype'] != 'ref': return None @@ -1137,7 +1137,7 @@ def warn_missing_reference(app: "Sphinx", domain: Domain, node: pending_xref return True -def setup(app: "Sphinx") -> dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_domain(StandardDomain) app.connect('warn-missing-reference', warn_missing_reference) diff --git a/sphinx/environment/__init__.py b/sphinx/environment/__init__.py index 47c904d69..a345971b5 100644 --- a/sphinx/environment/__init__.py +++ b/sphinx/environment/__init__.py @@ -141,7 +141,7 @@ class BuildEnvironment: # --------- ENVIRONMENT INITIALIZATION ------------------------------------- - def __init__(self, app: "Sphinx"): + def __init__(self, app: Sphinx): self.app: Sphinx = None self.doctreedir: str = None self.srcdir: str = None @@ -240,7 +240,7 @@ class BuildEnvironment: def __setstate__(self, state: dict) -> None: self.__dict__.update(state) - def setup(self, app: "Sphinx") -> None: + def setup(self, app: Sphinx) -> None: """Set up BuildEnvironment object.""" if self.version and self.version != app.registry.get_envversion(app): raise BuildEnvironmentError(__('build environment version not current')) @@ -286,14 +286,14 @@ class BuildEnvironment: extension = extensions[0] else: extension = '%d' % (len(extensions),) - self.config_status_extra = ' (%r)' % (extension,) + self.config_status_extra = f' ({extension!r})' else: # check if a config value was changed that affects how # doctrees are read for item in config.filter('env'): if self.config[item.name] != item.value: self.config_status = CONFIG_CHANGED - self.config_status_extra = ' (%r)' % (item.name,) + self.config_status_extra = f' ({item.name!r})' break self.config = config @@ -340,8 +340,8 @@ class BuildEnvironment: for domain in self.domains.values(): domain.clear_doc(docname) - def merge_info_from(self, docnames: list[str], other: "BuildEnvironment", - app: "Sphinx") -> None: + def merge_info_from(self, docnames: list[str], other: BuildEnvironment, + app: Sphinx) -> None: """Merge global information gathered about *docnames* while reading them from the *other* environment. @@ -397,7 +397,7 @@ class BuildEnvironment: """contains all existing docnames.""" return self.project.docnames - def find_files(self, config: Config, builder: "Builder") -> None: + def find_files(self, config: Config, builder: Builder) -> None: """Find all source files in the source dir and put them in self.found_docs. """ @@ -483,7 +483,7 @@ class BuildEnvironment: return added, changed, removed - def check_dependents(self, app: "Sphinx", already: set[str]) -> Generator[str, None, None]: + def check_dependents(self, app: Sphinx, already: set[str]) -> Generator[str, None, None]: to_rewrite: list[str] = [] for docnames in self.events.emit('env-get-updated', self): to_rewrite.extend(docnames) @@ -568,7 +568,7 @@ class BuildEnvironment: def get_and_resolve_doctree( self, docname: str, - builder: "Builder", + builder: Builder, doctree: nodes.document | None = None, prune_toctrees: bool = True, includehidden: bool = False @@ -594,7 +594,7 @@ class BuildEnvironment: return doctree - def resolve_toctree(self, docname: str, builder: "Builder", toctree: addnodes.toctree, + def resolve_toctree(self, docname: str, builder: Builder, toctree: addnodes.toctree, prune: bool = True, maxdepth: int = 0, titles_only: bool = False, collapse: bool = False, includehidden: bool = False) -> Node | None: """Resolve a *toctree* node into individual bullet lists with titles @@ -613,7 +613,7 @@ class BuildEnvironment: includehidden) def resolve_references(self, doctree: nodes.document, fromdocname: str, - builder: "Builder") -> None: + builder: Builder) -> None: self.apply_post_transforms(doctree, fromdocname) def apply_post_transforms(self, doctree: nodes.document, docname: str) -> None: diff --git a/sphinx/environment/adapters/toctree.py b/sphinx/environment/adapters/toctree.py index 84c3e8db6..4e0b6f007 100644 --- a/sphinx/environment/adapters/toctree.py +++ b/sphinx/environment/adapters/toctree.py @@ -22,7 +22,7 @@ logger = logging.getLogger(__name__) class TocTree: - def __init__(self, env: "BuildEnvironment") -> None: + def __init__(self, env: BuildEnvironment) -> None: self.env = env def note(self, docname: str, toctreenode: addnodes.toctree) -> None: @@ -40,7 +40,7 @@ class TocTree: self.env.files_to_rebuild.setdefault(includefile, set()).add(docname) self.env.toctree_includes.setdefault(docname, []).extend(includefiles) - def resolve(self, docname: str, builder: "Builder", toctree: addnodes.toctree, + def resolve(self, docname: str, builder: Builder, toctree: addnodes.toctree, prune: bool = True, maxdepth: int = 0, titles_only: bool = False, collapse: bool = False, includehidden: bool = False) -> Element | None: """Resolve a *toctree* node into individual bullet lists with titles @@ -305,7 +305,7 @@ class TocTree: # recurse on visible children self._toctree_prune(subnode, depth + 1, maxdepth, collapse) - def get_toc_for(self, docname: str, builder: "Builder") -> Node: + def get_toc_for(self, docname: str, builder: Builder) -> Node: """Return a TOC nodetree -- for use on the same page only!""" tocdepth = self.env.metadata[docname].get('tocdepth', 0) try: @@ -320,7 +320,7 @@ class TocTree: node['refuri'] = node['anchorname'] or '#' return toc - def get_toctree_for(self, docname: str, builder: "Builder", collapse: bool, + def get_toctree_for(self, docname: str, builder: Builder, collapse: bool, **kwargs: Any) -> Element | None: """Return the global TOC nodetree.""" doctree = self.env.get_doctree(self.env.config.root_doc) diff --git a/sphinx/environment/collectors/__init__.py b/sphinx/environment/collectors/__init__.py index 396d72cdf..f1e40b3bf 100644 --- a/sphinx/environment/collectors/__init__.py +++ b/sphinx/environment/collectors/__init__.py @@ -23,7 +23,7 @@ class EnvironmentCollector: listener_ids: dict[str, int] | None = None - def enable(self, app: "Sphinx") -> None: + def enable(self, app: Sphinx) -> None: assert self.listener_ids is None self.listener_ids = { 'doctree-read': app.connect('doctree-read', self.process_doc), @@ -33,38 +33,38 @@ class EnvironmentCollector: 'env-get-outdated': app.connect('env-get-outdated', self.get_outdated_docs), } - def disable(self, app: "Sphinx") -> None: + def disable(self, app: Sphinx) -> None: assert self.listener_ids is not None for listener_id in self.listener_ids.values(): app.disconnect(listener_id) self.listener_ids = None - def clear_doc(self, app: "Sphinx", env: BuildEnvironment, docname: str) -> None: + def clear_doc(self, app: Sphinx, env: BuildEnvironment, docname: str) -> None: """Remove specified data of a document. This method is called on the removal of the document.""" raise NotImplementedError - def merge_other(self, app: "Sphinx", env: BuildEnvironment, + def merge_other(self, app: Sphinx, env: BuildEnvironment, docnames: set[str], other: BuildEnvironment) -> None: """Merge in specified data regarding docnames from a different `BuildEnvironment` object which coming from a subprocess in parallel builds.""" raise NotImplementedError - def process_doc(self, app: "Sphinx", doctree: nodes.document) -> None: + def process_doc(self, app: Sphinx, doctree: nodes.document) -> None: """Process a document and gather specific data from it. This method is called after the document is read.""" raise NotImplementedError - def get_updated_docs(self, app: "Sphinx", env: BuildEnvironment) -> list[str]: + def get_updated_docs(self, app: Sphinx, env: BuildEnvironment) -> list[str]: """Return a list of docnames to re-read. This methods is called after reading the whole of documents (experimental). """ return [] - def get_outdated_docs(self, app: "Sphinx", env: BuildEnvironment, + def get_outdated_docs(self, app: Sphinx, env: BuildEnvironment, added: set[str], changed: set[str], removed: set[str]) -> list[str]: """Return a list of docnames to re-read. diff --git a/sphinx/errors.py b/sphinx/errors.py index a9172e07b..437e4acd9 100644 --- a/sphinx/errors.py +++ b/sphinx/errors.py @@ -58,14 +58,13 @@ class ExtensionError(SphinxError): def __repr__(self) -> str: if self.orig_exc: - return '%s(%r, %r)' % (self.__class__.__name__, - self.message, self.orig_exc) - return '%s(%r)' % (self.__class__.__name__, self.message) + return f'{self.__class__.__name__}({self.message!r}, {self.orig_exc!r})' + return f'{self.__class__.__name__}({self.message!r})' def __str__(self) -> str: parent_str = super().__str__() if self.orig_exc: - return '%s (exception: %s)' % (parent_str, self.orig_exc) + return f'{parent_str} (exception: {self.orig_exc})' return parent_str diff --git a/sphinx/events.py b/sphinx/events.py index 5f97279bf..5b34e56d8 100644 --- a/sphinx/events.py +++ b/sphinx/events.py @@ -50,7 +50,7 @@ core_events = { class EventManager: """Event manager for Sphinx.""" - def __init__(self, app: "Sphinx") -> None: + def __init__(self, app: Sphinx) -> None: self.app = app self.events = core_events.copy() self.listeners: dict[str, list[EventListener]] = defaultdict(list) diff --git a/sphinx/ext/apidoc.py b/sphinx/ext/apidoc.py index e706fb226..8a4808c3b 100644 --- a/sphinx/ext/apidoc.py +++ b/sphinx/ext/apidoc.py @@ -73,7 +73,7 @@ def write_file(name: str, text: str, opts: Any) -> None: """Write the output file for module/package <name>.""" quiet = getattr(opts, 'quiet', None) - fname = path.join(opts.destdir, '%s.%s' % (name, opts.suffix)) + fname = path.join(opts.destdir, f'{name}.{opts.suffix}') if opts.dryrun: if not quiet: print(__('Would create file %s.') % fname) diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py index e8fbd3865..35b16673e 100644 --- a/sphinx/ext/autodoc/__init__.py +++ b/sphinx/ext/autodoc/__init__.py @@ -234,7 +234,7 @@ def between( # But we define this class here to keep compatibility (see #4538) class Options(dict): """A dict/attribute hybrid that returns None on nonexisting keys.""" - def copy(self) -> "Options": + def copy(self) -> Options: return Options(super().copy()) def __getattr__(self, name: str) -> Any: @@ -314,7 +314,7 @@ class Documenter: """Called to see if a member can be documented by this Documenter.""" raise NotImplementedError('must be implemented in subclasses') - def __init__(self, directive: "DocumenterBridge", name: str, indent: str = '') -> None: + def __init__(self, directive: DocumenterBridge, name: str, indent: str = '') -> None: self.directive = directive self.config: Config = directive.env.config self.env: BuildEnvironment = directive.env @@ -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 @@ -515,9 +515,9 @@ class Documenter: sourcename = self.get_sourcename() # one signature per line, indented by column - prefix = '.. %s:%s:: ' % (domain, directive) + prefix = f'.. {domain}:{directive}:: ' for i, sig_line in enumerate(sig.split("\n")): - self.add_line('%s%s%s' % (prefix, name, sig_line), + self.add_line(f'{prefix}{name}{sig_line}', sourcename) if i == 0: prefix = " " * len(prefix) @@ -562,12 +562,12 @@ class Documenter: inspect.safe_getattr(self.object, '__qualname__', None)): # Get the correct location of docstring from self.object # to support inherited methods - fullname = '%s.%s' % (self.object.__module__, self.object.__qualname__) + fullname = f'{self.object.__module__}.{self.object.__qualname__}' else: fullname = self.fullname if self.analyzer: - return '%s:docstring of %s' % (self.analyzer.srcname, fullname) + return f'{self.analyzer.srcname}:docstring of {fullname}' else: return 'docstring of %s' % fullname @@ -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 @@ -1075,8 +1075,8 @@ 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) @@ -1200,7 +1200,7 @@ class DocstringSignatureMixin: result = args, retann else: # subsequent signatures - self._signatures.append("(%s) -> %s" % (args, retann)) + self._signatures.append(f"({args}) -> {retann}") if result: # finish the loop when signature found @@ -1478,7 +1478,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: call = get_user_defined_function_or_method(type(self.object), '__call__') if call is not None: - if "{0.__module__}.{0.__qualname__}".format(call) in _METACLASS_CALL_BLACKLIST: + if f"{call.__module__}.{call.__qualname__}" in _METACLASS_CALL_BLACKLIST: call = None if call is not None: @@ -1494,7 +1494,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: new = get_user_defined_function_or_method(self.object, '__new__') if new is not None: - if "{0.__module__}.{0.__qualname__}".format(new) in _CLASS_NEW_BLACKLIST: + if f"{new.__module__}.{new.__qualname__}" in _CLASS_NEW_BLACKLIST: new = None if new is not None: diff --git a/sphinx/ext/autodoc/importer.py b/sphinx/ext/autodoc/importer.py index 5fa95edcd..64a4dd520 100644 --- a/sphinx/ext/autodoc/importer.py +++ b/sphinx/ext/autodoc/importer.py @@ -23,7 +23,7 @@ def mangle(subject: Any, name: str) -> str: """Mangle the given name.""" try: if isclass(subject) and name.startswith('__') and not name.endswith('__'): - return "_%s%s" % (subject.__name__, name) + return f"_{subject.__name__}{name}" except AttributeError: pass @@ -117,7 +117,7 @@ def import_object(modname: str, objpath: list[str], objtype: str = '', errmsg = ('autodoc: failed to import %s %r from module %r' % (objtype, '.'.join(objpath), modname)) else: - errmsg = 'autodoc: failed to import %s %r' % (objtype, modname) + errmsg = f'autodoc: failed to import {objtype} {modname!r}' if isinstance(exc, ImportError): # import_module() raises ImportError having real exception obj and @@ -209,7 +209,7 @@ def get_object_members( def get_class_members(subject: Any, objpath: list[str], attrgetter: Callable, - inherit_docstrings: bool = True) -> dict[str, "ObjectMember"]: + inherit_docstrings: bool = True) -> dict[str, ObjectMember]: """Get members and attributes of target class.""" from sphinx.ext.autodoc import INSTANCEATTR, ObjectMember diff --git a/sphinx/ext/autodoc/mock.py b/sphinx/ext/autodoc/mock.py index 6bc2e8f1e..bae0504ae 100644 --- a/sphinx/ext/autodoc/mock.py +++ b/sphinx/ext/autodoc/mock.py @@ -49,10 +49,10 @@ class _MockObject: def __mro_entries__(self, bases: tuple) -> tuple: return (self.__class__,) - def __getitem__(self, key: Any) -> "_MockObject": + def __getitem__(self, key: Any) -> _MockObject: return _make_subclass(str(key), self.__display_name__, self.__class__)() - def __getattr__(self, key: str) -> "_MockObject": + def __getattr__(self, key: str) -> _MockObject: return _make_subclass(key, self.__display_name__, self.__class__)() def __call__(self, *args: Any, **kwargs: Any) -> Any: @@ -94,7 +94,7 @@ class _MockModule(ModuleType): class MockLoader(Loader): """A loader for mocking.""" - def __init__(self, finder: "MockFinder") -> None: + def __init__(self, finder: MockFinder) -> None: super().__init__() self.finder = finder diff --git a/sphinx/ext/autosummary/__init__.py b/sphinx/ext/autosummary/__init__.py index be8187624..68f569e48 100644 --- a/sphinx/ext/autosummary/__init__.py +++ b/sphinx/ext/autosummary/__init__.py @@ -283,7 +283,7 @@ class Autosummary(SphinxDirective): raise ImportExceptionGroup(exc.args[0], errors) def create_documenter(self, app: Sphinx, obj: Any, - parent: Any, full_name: str) -> "Documenter": + parent: Any, full_name: str) -> Documenter: """Get an autodoc.Documenter class suitable for documenting the given object. @@ -311,7 +311,7 @@ class Autosummary(SphinxDirective): try: real_name, obj, parent, modname = self.import_by_name(name, prefixes=prefixes) except ImportExceptionGroup as exc: - errors = list({"* %s: %s" % (type(e).__name__, e) for e in exc.exceptions}) + errors = list({f"* {type(e).__name__}: {e}" for e in exc.exceptions}) logger.warning(__('autosummary: failed to import %s.\nPossible hints:\n%s'), name, '\n'.join(errors), location=self.get_location()) continue @@ -412,9 +412,9 @@ class Autosummary(SphinxDirective): for name, sig, summary, real_name in items: qualifier = 'obj' if 'nosignatures' not in self.options: - col1 = ':py:%s:`%s <%s>`\\ %s' % (qualifier, name, real_name, rst.escape(sig)) + col1 = f':py:{qualifier}:`{name} <{real_name}>`\\ {rst.escape(sig)}' else: - col1 = ':py:%s:`%s <%s>`' % (qualifier, name, real_name) + col1 = f':py:{qualifier}:`{name} <{real_name}>`' col2 = summary append_row(col1, col2) diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py index 4681fe3ec..f35d10447 100644 --- a/sphinx/ext/autosummary/generate.py +++ b/sphinx/ext/autosummary/generate.py @@ -407,7 +407,7 @@ def generate_autosummary_docs(sources: list[str], output_dir: str | None = None, else: exceptions = exc.exceptions + [exc2] - errors = list({"* %s: %s" % (type(e).__name__, e) for e in exceptions}) + errors = list({f"* {type(e).__name__}: {e}" for e in exceptions}) logger.warning(__('[autosummary] failed to import %s.\nPossible hints:\n%s'), entry.name, '\n'.join(errors)) continue @@ -473,8 +473,8 @@ def find_autosummary_in_docstring( except AttributeError: pass except ImportExceptionGroup as exc: - errors = list({"* %s: %s" % (type(e).__name__, e) for e in exc.exceptions}) - print('Failed to import %s.\nPossible hints:\n%s' % (name, '\n'.join(errors))) + errors = '\n'.join({f"* {type(e).__name__}: {e}" for e in exc.exceptions}) + print(f'Failed to import {name}.\nPossible hints:\n{errors}') except SystemExit: print("Failed to import '%s'; the module executes module level " "statement and it might call sys.exit()." % name) @@ -543,7 +543,7 @@ def find_autosummary_in_lines( name = name[1:] if current_module and \ not name.startswith(current_module + '.'): - name = "%s.%s" % (current_module, name) + name = f"{current_module}.{name}" documented.append(AutosummaryEntry(name, toctree, template, recursive)) continue diff --git a/sphinx/ext/coverage.py b/sphinx/ext/coverage.py index da2a72b54..362a644f5 100644 --- a/sphinx/ext/coverage.py +++ b/sphinx/ext/coverage.py @@ -172,7 +172,7 @@ class CoverageBuilder(Builder): # is not defined in this module continue - full_name = '%s.%s' % (mod_name, name) + full_name = f'{mod_name}.{name}' if self.ignore_pyobj(full_name): continue @@ -215,7 +215,7 @@ class CoverageBuilder(Builder): if skip_undoc and not attr.__doc__: # skip methods without docstring if wished continue - full_attr_name = '%s.%s' % (full_name, attr_name) + full_attr_name = f'{full_name}.{attr_name}' if self.ignore_pyobj(full_attr_name): continue if full_attr_name not in objects: diff --git a/sphinx/ext/doctest.py b/sphinx/ext/doctest.py index 650ed8a3f..e6981848a 100644 --- a/sphinx/ext/doctest.py +++ b/sphinx/ext/doctest.py @@ -195,7 +195,7 @@ class TestGroup: self.tests: list[list[TestCode]] = [] self.cleanup: list[TestCode] = [] - def add_code(self, code: "TestCode", prepend: bool = False) -> None: + def add_code(self, code: TestCode, prepend: bool = False) -> None: if code.type == 'testsetup': if prepend: self.setup.insert(0, code) @@ -214,8 +214,8 @@ class TestGroup: raise RuntimeError(__('invalid TestCode type')) def __repr__(self) -> str: - return 'TestGroup(name=%r, setup=%r, cleanup=%r, tests=%r)' % ( - self.name, self.setup, self.cleanup, self.tests) + return (f'TestGroup(name={self.name!r}, setup={self.setup!r}, ' + f'cleanup={self.cleanup!r}, tests={self.tests!r})') class TestCode: @@ -228,8 +228,8 @@ class TestCode: self.options = options or {} def __repr__(self) -> str: - return 'TestCode(%r, %r, filename=%r, lineno=%r, options=%r)' % ( - self.code, self.type, self.filename, self.lineno, self.options) + return (f'TestCode({self.code!r}, {self.type!r}, filename={self.filename!r}, ' + f'lineno={self.lineno!r}, options={self.options!r})') class SphinxDocTestRunner(doctest.DocTestRunner): @@ -482,7 +482,7 @@ Doctest summary return True # simulate a doctest with the code sim_doctest = doctest.DocTest(examples, {}, - '%s (%s code)' % (group.name, what), + f'{group.name} ({what} code)', testcodes[0].filename, 0, None) sim_doctest.globs = ns old_f = runner.failures @@ -542,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/graphviz.py b/sphinx/ext/graphviz.py index b9b2c1558..8023d6ef8 100644 --- a/sphinx/ext/graphviz.py +++ b/sphinx/ext/graphviz.py @@ -219,7 +219,7 @@ def render_dot(self: SphinxTranslator, code: str, options: dict, format: str, hashkey = (code + str(options) + str(graphviz_dot) + str(self.builder.config.graphviz_dot_args)).encode() - fname = '%s-%s.%s' % (prefix, sha1(hashkey).hexdigest(), format) + fname = f'{prefix}-{sha1(hashkey).hexdigest()}.{format}' relfn = posixpath.join(self.builder.imgpath, fname) outfn = path.join(self.builder.outdir, self.builder.imagedir, fname) diff --git a/sphinx/ext/inheritance_diagram.py b/sphinx/ext/inheritance_diagram.py index e134bd753..634c7b5dc 100644 --- a/sphinx/ext/inheritance_diagram.py +++ b/sphinx/ext/inheritance_diagram.py @@ -227,7 +227,7 @@ class InheritanceGraph: if module in ('__builtin__', 'builtins'): fullname = cls.__name__ else: - fullname = '%s.%s' % (module, cls.__qualname__) + fullname = f'{module}.{cls.__qualname__}' if parts == 0: result = fullname else: diff --git a/sphinx/ext/napoleon/docstring.py b/sphinx/ext/napoleon/docstring.py index cb8a5e1cd..8594cdfc3 100644 --- a/sphinx/ext/napoleon/docstring.py +++ b/sphinx/ext/napoleon/docstring.py @@ -410,7 +410,7 @@ class GoogleDocstring: 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()), ''] + return [f'.. {admonition}:: {lines[0].strip()}', ''] elif lines: lines = self._indent(self._dedent(lines), 3) return ['.. %s::' % admonition, ''] + lines + [''] @@ -443,13 +443,13 @@ class GoogleDocstring: _desc = self._strip_empty(_desc) if any(_desc): _desc = self._fix_field_desc(_desc) - field = ':%s %s: ' % (field_role, _name) + field = f':{field_role} {_name}: ' lines.extend(self._format_block(field, _desc)) else: - lines.append(':%s %s:' % (field_role, _name)) + lines.append(f':{field_role} {_name}:') if _type: - lines.append(':%s %s: %s' % (type_role, _name, _type)) + lines.append(f':{type_role} {_name}: {_type}') return lines + [''] def _format_field(self, _name: str, _type: str, _desc: list[str]) -> list[str]: @@ -459,16 +459,16 @@ class GoogleDocstring: if _name: if _type: if '`' in _type: - field = '**%s** (%s)%s' % (_name, _type, separator) + field = f'**{_name}** ({_type}){separator}' else: - field = '**%s** (*%s*)%s' % (_name, _type, separator) + field = f'**{_name}** (*{_type}*){separator}' else: - field = '**%s**%s' % (_name, separator) + field = f'**{_name}**{separator}' elif _type: if '`' in _type: - field = '%s%s' % (_type, separator) + field = f'{_type}{separator}' else: - field = '*%s*%s' % (_type, separator) + field = f'*{_type}*{separator}' else: field = '' @@ -657,7 +657,7 @@ class GoogleDocstring: field = ':ivar %s: ' % _name lines.extend(self._format_block(field, _desc)) if _type: - lines.append(':vartype %s: %s' % (_name, _type)) + lines.append(f':vartype {_name}: {_type}') else: lines.append('.. attribute:: ' + _name) if self._opt and 'noindex' in self._opt: @@ -770,7 +770,7 @@ class GoogleDocstring: _type = ' ' + _type if _type else '' _desc = self._strip_empty(_desc) _descs = ' ' + '\n '.join(_desc) if any(_desc) else '' - lines.append(':raises%s:%s' % (_type, _descs)) + lines.append(f':raises{_type}:{_descs}') if lines: lines.append('') return lines @@ -1338,7 +1338,7 @@ class NumpyDocstring(GoogleDocstring): last_had_desc = True for name, desc, role in items: if role: - link = ':%s:`%s`' % (role, name) + link = f':{role}:`{name}`' else: link = ':obj:`%s`' % name if desc or last_had_desc: diff --git a/sphinx/ext/napoleon/iterators.py b/sphinx/ext/napoleon/iterators.py index 750e1b3e0..2861caa7d 100644 --- a/sphinx/ext/napoleon/iterators.py +++ b/sphinx/ext/napoleon/iterators.py @@ -54,7 +54,7 @@ class peek_iter: else: self.sentinel = object() - def __iter__(self) -> "peek_iter": + def __iter__(self) -> peek_iter: return self def __next__(self, n: int | None = None) -> Any: diff --git a/sphinx/ext/viewcode.py b/sphinx/ext/viewcode.py index 5bde12d6c..183c18406 100644 --- a/sphinx/ext/viewcode.py +++ b/sphinx/ext/viewcode.py @@ -307,10 +307,9 @@ def collect_pages(app: Sphinx) -> Generator[tuple[str, dict[str, Any], str], Non stack.pop() html.append('</ul>') stack.append(modname + '.') - html.append('<li><a href="%s">%s</a></li>\n' % ( - urito(posixpath.join(OUTPUT_DIRNAME, 'index'), - posixpath.join(OUTPUT_DIRNAME, modname.replace('.', '/'))), - modname)) + relative_uri = urito(posixpath.join(OUTPUT_DIRNAME, 'index'), + posixpath.join(OUTPUT_DIRNAME, modname.replace('.', '/'))) + html.append(f'<li><a href="{relative_uri}">{modname}</a></li>\n') html.append('</ul>' * (len(stack) - 1)) context = { 'title': _('Overview: module code'), diff --git a/sphinx/extension.py b/sphinx/extension.py index 0b1a4e56b..15f2afa09 100644 --- a/sphinx/extension.py +++ b/sphinx/extension.py @@ -35,7 +35,7 @@ class Extension: self.parallel_write_safe = kwargs.pop('parallel_write_safe', True) -def verify_needs_extensions(app: "Sphinx", config: Config) -> None: +def verify_needs_extensions(app: Sphinx, config: Config) -> None: """Check that extensions mentioned in :confval:`needs_extensions` satisfy the version requirement, and warn if an extension is not loaded. @@ -72,7 +72,7 @@ def verify_needs_extensions(app: "Sphinx", config: Config) -> None: (extname, reqversion, extension.version)) -def setup(app: "Sphinx") -> dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.connect('config-inited', verify_needs_extensions, priority=800) return { diff --git a/sphinx/highlighting.py b/sphinx/highlighting.py index 7ed933f43..fc2c6fa4b 100644 --- a/sphinx/highlighting.py +++ b/sphinx/highlighting.py @@ -4,7 +4,7 @@ from __future__ import annotations from functools import partial from importlib import import_module -from typing import Any, Union +from typing import Any from pygments import highlight from pygments.filters import ErrorToken @@ -24,7 +24,7 @@ from sphinx.util import logging, texescape logger = logging.getLogger(__name__) lexers: dict[str, Lexer] = {} -lexer_classes: dict[str, Union[type[Lexer], 'partial[Lexer]']] = { +lexer_classes: dict[str, type[Lexer] | partial[Lexer]] = { 'none': partial(TextLexer, stripnl=False), 'python': partial(PythonLexer, stripnl=False), 'pycon': partial(PythonConsoleLexer, stripnl=False), diff --git a/sphinx/io.py b/sphinx/io.py index e4cf9588c..e2ec1e400 100644 --- a/sphinx/io.py +++ b/sphinx/io.py @@ -53,7 +53,7 @@ class SphinxBaseReader(standalone.Reader): super().__init__(*args, **kwargs) - def setup(self, app: "Sphinx") -> None: + def setup(self, app: Sphinx) -> None: self._app = app # hold application object only for compatibility self._env = app.env @@ -92,7 +92,7 @@ class SphinxStandaloneReader(SphinxBaseReader): A basic document reader for Sphinx. """ - def setup(self, app: "Sphinx") -> None: + def setup(self, app: Sphinx) -> None: self.transforms = self.transforms + app.registry.get_transforms() super().setup(app) @@ -124,7 +124,7 @@ class SphinxI18nReader(SphinxBaseReader): Because the translated texts are partial and they don't have correct line numbers. """ - def setup(self, app: "Sphinx") -> None: + def setup(self, app: Sphinx) -> None: super().setup(app) self.transforms = self.transforms + app.registry.get_transforms() @@ -157,7 +157,7 @@ class SphinxFileInput(FileInput): super().__init__(*args, **kwargs) -def read_doc(app: "Sphinx", env: BuildEnvironment, filename: str) -> nodes.document: +def read_doc(app: Sphinx, env: BuildEnvironment, filename: str) -> nodes.document: """Parse a document and convert to doctree.""" warnings.warn('sphinx.io.read_doc() is deprecated.', RemovedInSphinx70Warning, stacklevel=2) @@ -189,7 +189,7 @@ def read_doc(app: "Sphinx", env: BuildEnvironment, filename: str) -> nodes.docum return pub.document -def create_publisher(app: "Sphinx", filetype: str) -> Publisher: +def create_publisher(app: Sphinx, filetype: str) -> Publisher: reader = SphinxStandaloneReader() reader.setup(app) diff --git a/sphinx/jinja2glue.py b/sphinx/jinja2glue.py index c19257c72..0324b3fea 100644 --- a/sphinx/jinja2glue.py +++ b/sphinx/jinja2glue.py @@ -105,7 +105,7 @@ class idgen: def warning(context: dict, message: str, *args: Any, **kwargs: Any) -> str: if 'pagename' in context: filename = context.get('pagename') + context.get('file_suffix', '') - message = 'in rendering %s: %s' % (filename, message) + message = f'in rendering {filename}: {message}' logger = logging.getLogger('sphinx.themes') logger.warning(message, *args, **kwargs) return '' # return empty string not to output any values @@ -146,7 +146,7 @@ class BuiltinTemplateLoader(TemplateBridge, BaseLoader): def init( self, - builder: "Builder", + builder: Builder, theme: Theme | None = None, dirs: list[str] | None = None ) -> None: diff --git a/sphinx/parsers.py b/sphinx/parsers.py index 3f03501e2..3bcd69f52 100644 --- a/sphinx/parsers.py +++ b/sphinx/parsers.py @@ -35,7 +35,7 @@ class Parser(docutils.parsers.Parser): #: The environment object env: BuildEnvironment - def set_application(self, app: "Sphinx") -> None: + def set_application(self, app: Sphinx) -> None: """set_application will be called from Sphinx to set app and other instance variables :param sphinx.application.Sphinx app: Sphinx application object @@ -86,7 +86,7 @@ class RSTParser(docutils.parsers.rst.Parser, Parser): append_epilog(content, self.config.rst_epilog) -def setup(app: "Sphinx") -> dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_source_parser(RSTParser) return { diff --git a/sphinx/project.py b/sphinx/project.py index 89e003b22..cb4a71f58 100644 --- a/sphinx/project.py +++ b/sphinx/project.py @@ -28,7 +28,7 @@ class Project: #: The name of documents belongs to this project. self.docnames: set[str] = set() - def restore(self, other: "Project") -> None: + def restore(self, other: Project) -> None: """Take over a result of last build.""" self.docnames = other.docnames diff --git a/sphinx/pycode/__init__.py b/sphinx/pycode/__init__.py index c11579f96..19e478f57 100644 --- a/sphinx/pycode/__init__.py +++ b/sphinx/pycode/__init__.py @@ -76,11 +76,11 @@ class ModuleAnalyzer: @classmethod def for_string(cls, string: str, modname: str, srcname: str = '<string>' - ) -> "ModuleAnalyzer": + ) -> ModuleAnalyzer: return cls(string, modname, srcname) @classmethod - def for_file(cls, filename: str, modname: str) -> "ModuleAnalyzer": + def for_file(cls, filename: str, modname: str) -> ModuleAnalyzer: if ('file', filename) in cls.cache: return cls.cache['file', filename] try: @@ -96,7 +96,7 @@ class ModuleAnalyzer: return obj @classmethod - def for_egg(cls, filename: str, modname: str) -> "ModuleAnalyzer": + def for_egg(cls, filename: str, modname: str) -> ModuleAnalyzer: SEP = re.escape(path.sep) eggpath, relpath = re.split('(?<=\\.egg)' + SEP, filename) try: @@ -107,7 +107,7 @@ class ModuleAnalyzer: raise PycodeError('error opening %r' % filename, exc) from exc @classmethod - def for_module(cls, modname: str) -> "ModuleAnalyzer": + def for_module(cls, modname: str) -> ModuleAnalyzer: if ('module', modname) in cls.cache: entry = cls.cache['module', modname] if isinstance(entry, PycodeError): @@ -158,7 +158,7 @@ class ModuleAnalyzer: self.tagorder = parser.deforders self._analyzed = True except Exception as exc: - raise PycodeError('parsing %r failed: %r' % (self.srcname, exc)) from exc + raise PycodeError(f'parsing {self.srcname!r} failed: {exc!r}') from exc def find_attr_docs(self) -> dict[tuple[str, str], list[str]]: """Find class and module-level attributes and their documentation.""" diff --git a/sphinx/pycode/ast.py b/sphinx/pycode/ast.py index b85edb1b5..702006817 100644 --- a/sphinx/pycode/ast.py +++ b/sphinx/pycode/ast.py @@ -31,7 +31,7 @@ OPERATORS: dict[type[ast.AST], str] = { } -def parse(code: str, mode: str = 'exec') -> "ast.AST": +def parse(code: str, mode: str = 'exec') -> ast.AST: """Parse the *code* using the built-in ast module.""" warnings.warn( "'sphinx.pycode.ast.parse' is deprecated, use 'ast.parse' instead.", @@ -76,7 +76,7 @@ class _UnparseVisitor(ast.NodeVisitor): def visit_arg(self, node: ast.arg) -> str: if node.annotation: - return "%s: %s" % (node.arg, self.visit(node.annotation)) + return f"{node.arg}: {self.visit(node.annotation)}" else: return node.arg @@ -126,7 +126,7 @@ class _UnparseVisitor(ast.NodeVisitor): return ", ".join(args) def visit_Attribute(self, node: ast.Attribute) -> str: - return "%s.%s" % (self.visit(node.value), node.attr) + return f"{self.visit(node.value)}.{node.attr}" def visit_BinOp(self, node: ast.BinOp) -> str: # Special case ``**`` to not have surrounding spaces. @@ -139,9 +139,9 @@ class _UnparseVisitor(ast.NodeVisitor): return op.join(self.visit(e) for e in node.values) def visit_Call(self, node: ast.Call) -> str: - args = ([self.visit(e) for e in node.args] + - ["%s=%s" % (k.arg, self.visit(k.value)) for k in node.keywords]) - return "%s(%s)" % (self.visit(node.func), ", ".join(args)) + args = ', '.join([self.visit(e) for e in node.args] + + [f"{k.arg}={self.visit(k.value)}" for k in node.keywords]) + return f"{self.visit(node.func)}({args})" def visit_Constant(self, node: ast.Constant) -> str: if node.value is Ellipsis: @@ -185,19 +185,19 @@ class _UnparseVisitor(ast.NodeVisitor): if is_simple_tuple(node.slice): elts = ", ".join(self.visit(e) for e in node.slice.elts) # type: ignore - return "%s[%s]" % (self.visit(node.value), elts) + return f"{self.visit(node.value)}[{elts}]" elif isinstance(node.slice, ast.Index) and is_simple_tuple(node.slice.value): elts = ", ".join(self.visit(e) for e in node.slice.value.elts) # type: ignore - return "%s[%s]" % (self.visit(node.value), elts) + return f"{self.visit(node.value)}[{elts}]" else: - return "%s[%s]" % (self.visit(node.value), self.visit(node.slice)) + return f"{self.visit(node.value)}[{self.visit(node.slice)}]" def visit_UnaryOp(self, node: ast.UnaryOp) -> str: # UnaryOp is one of {UAdd, USub, Invert, Not}, which refer to ``+x``, # ``-x``, ``~x``, and ``not x``. Only Not needs a space. if isinstance(node.op, ast.Not): - return "%s %s" % (self.visit(node.op), self.visit(node.operand)) - return "%s%s" % (self.visit(node.op), self.visit(node.operand)) + return f"{self.visit(node.op)} {self.visit(node.operand)}" + return f"{self.visit(node.op)}{self.visit(node.operand)}" def visit_Tuple(self, node: ast.Tuple) -> str: if len(node.elts) == 0: diff --git a/sphinx/pycode/parser.py b/sphinx/pycode/parser.py index 68a3523b3..7dd924822 100644 --- a/sphinx/pycode/parser.py +++ b/sphinx/pycode/parser.py @@ -118,8 +118,7 @@ class Token: return any(self == candidate for candidate in conditions) def __repr__(self) -> str: - return '<Token kind=%r value=%r>' % (tokenize.tok_name[self.kind], - self.value.strip()) + return f'<Token kind={tokenize.tok_name[self.kind]!r} value={self.value.strip()!r}>' class TokenProcessor: diff --git a/sphinx/registry.py b/sphinx/registry.py index 14581b8cb..fd09544be 100644 --- a/sphinx/registry.py +++ b/sphinx/registry.py @@ -136,7 +136,7 @@ class SphinxComponentRegistry: (builder.name, self.builders[builder.name].__module__)) self.builders[builder.name] = builder - def preload_builder(self, app: "Sphinx", name: str) -> None: + def preload_builder(self, app: Sphinx, name: str) -> None: if name is None: return @@ -150,7 +150,7 @@ class SphinxComponentRegistry: self.load_extension(app, entry_point.module) - def create_builder(self, app: "Sphinx", name: str, + def create_builder(self, app: Sphinx, name: str, env: BuildEnvironment | None = None) -> Builder: if name not in self.builders: raise SphinxError(__('Builder name %s not registered') % name) @@ -309,7 +309,7 @@ class SphinxComponentRegistry: def get_source_parsers(self) -> dict[str, type[Parser]]: return self.source_parsers - def create_source_parser(self, app: "Sphinx", filename: str) -> Parser: + def create_source_parser(self, app: Sphinx, filename: str) -> Parser: parser_class = self.get_source_parser(filename) parser = parser_class() if isinstance(parser, SphinxParser): @@ -373,7 +373,7 @@ class SphinxComponentRegistry: def get_post_transforms(self) -> list[type[Transform]]: return self.post_transforms - def add_documenter(self, objtype: str, documenter: type["Documenter"]) -> None: + def add_documenter(self, objtype: str, documenter: type[Documenter]) -> None: self.documenters[objtype] = documenter def add_autodoc_attrgetter(self, typ: type, @@ -426,7 +426,7 @@ class SphinxComponentRegistry: def add_html_theme(self, name: str, theme_path: str) -> None: self.html_themes[name] = theme_path - def load_extension(self, app: "Sphinx", extname: str) -> None: + def load_extension(self, app: Sphinx, extname: str) -> None: """Load a Sphinx extension.""" if extname in app.extensions: # already loaded return @@ -472,14 +472,14 @@ class SphinxComponentRegistry: app.extensions[extname] = Extension(extname, mod, **metadata) - def get_envversion(self, app: "Sphinx") -> dict[str, str]: + def get_envversion(self, app: Sphinx) -> dict[str, str]: from sphinx.environment import ENV_VERSION envversion = {ext.name: ext.metadata['env_version'] for ext in app.extensions.values() if ext.metadata.get('env_version')} envversion['sphinx'] = ENV_VERSION return envversion - def get_publisher(self, app: "Sphinx", filetype: str) -> Publisher: + def get_publisher(self, app: Sphinx, filetype: str) -> Publisher: try: return self.publishers[filetype] except KeyError: @@ -489,7 +489,7 @@ class SphinxComponentRegistry: return publisher -def merge_source_suffix(app: "Sphinx", config: Config) -> None: +def merge_source_suffix(app: Sphinx, config: Config) -> None: """Merge any user-specified source_suffix with any added by extensions.""" for suffix, filetype in app.registry.source_suffix.items(): if suffix not in app.config.source_suffix: @@ -503,7 +503,7 @@ def merge_source_suffix(app: "Sphinx", config: Config) -> None: app.registry.source_suffix = app.config.source_suffix -def setup(app: "Sphinx") -> dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.connect('config-inited', merge_source_suffix, priority=800) return { diff --git a/sphinx/roles.py b/sphinx/roles.py index d682b4cb7..fa80defb7 100644 --- a/sphinx/roles.py +++ b/sphinx/roles.py @@ -98,7 +98,7 @@ class XRefRole(ReferenceRole): self.classes = ['xref', self.reftype] else: self.refdomain, self.reftype = self.name.split(':', 1) - self.classes = ['xref', self.refdomain, '%s-%s' % (self.refdomain, self.reftype)] + self.classes = ['xref', self.refdomain, f'{self.refdomain}-{self.reftype}'] if self.disabled: return self.create_non_xref_node() @@ -141,7 +141,7 @@ class XRefRole(ReferenceRole): # methods that can be overwritten - def process_link(self, env: "BuildEnvironment", refnode: Element, has_explicit_title: bool, + def process_link(self, env: BuildEnvironment, refnode: Element, has_explicit_title: bool, title: str, target: str) -> tuple[str, str]: """Called after parsing title and target text, and creating the reference node (given in *refnode*). This method can alter the @@ -150,7 +150,7 @@ class XRefRole(ReferenceRole): """ return title, ws_re.sub(' ', target) - def result_nodes(self, document: nodes.document, env: "BuildEnvironment", node: Element, + def result_nodes(self, document: nodes.document, env: BuildEnvironment, node: Element, is_ref: bool) -> tuple[list[Node], list[system_message]]: """Called before returning the finished nodes. *node* is the reference node if one was created (*is_ref* is then true), else the content node. @@ -161,7 +161,7 @@ class XRefRole(ReferenceRole): class AnyXRefRole(XRefRole): - def process_link(self, env: "BuildEnvironment", refnode: Element, has_explicit_title: bool, + def process_link(self, env: BuildEnvironment, refnode: Element, has_explicit_title: bool, title: str, target: str) -> tuple[str, str]: result = super().process_link(env, refnode, has_explicit_title, title, target) # add all possible context info (i.e. std:program, py:module etc.) @@ -406,7 +406,7 @@ specific_docroles: dict[str, RoleFunction] = { } -def setup(app: "Sphinx") -> dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: from docutils.parsers.rst import roles for rolename, nodeclass in generic_docroles.items(): diff --git a/sphinx/search/__init__.py b/sphinx/search/__init__.py index 1d4df7d0e..8b185915e 100644 --- a/sphinx/search/__init__.py +++ b/sphinx/search/__init__.py @@ -50,11 +50,11 @@ class SearchLanguage: This class is used to preprocess search word which Sphinx HTML readers type, before searching index. Default implementation does nothing. """ - lang: Optional[str] = None - language_name: Optional[str] = None - stopwords: Set[str] = set() + lang: str | None = None + language_name: str | None = None + stopwords: set[str] = set() js_splitter_code: str = "" - js_stemmer_rawcode: Optional[str] = None + js_stemmer_rawcode: str | None = None js_stemmer_code = """ /** * Dummy stemmer for languages without stemming rules. @@ -68,16 +68,16 @@ var Stemmer = function() { _word_re = re.compile(r'(?u)\w+') - def __init__(self, options: Dict) -> None: + def __init__(self, options: dict) -> None: self.options = options self.init(options) - def init(self, options: Dict) -> None: + def init(self, options: dict) -> None: """ Initialize the class with the options the user has given. """ - def split(self, input: str) -> List[str]: + def split(self, input: str) -> list[str]: """ This method splits a sentence into words. Default splitter splits input at white spaces, which should be enough for most languages except CJK @@ -115,13 +115,13 @@ var Stemmer = function() { from sphinx.search.en import SearchEnglish -def parse_stop_word(source: str) -> Set[str]: +def parse_stop_word(source: str) -> set[str]: """ Parse snowball style word list like this: * http://snowball.tartarus.org/algorithms/finnish/stop.txt """ - result: Set[str] = set() + result: set[str] = set() for line in source.splitlines(): line = line.split('|')[0] # remove comment result.update(line.split()) @@ -129,7 +129,7 @@ def parse_stop_word(source: str) -> Set[str]: # maps language name to module.class or directly a class -languages: Dict[str, Union[str, Type[SearchLanguage]]] = { +languages: dict[str, str | type[SearchLanguage]] = { 'da': 'sphinx.search.da.SearchDanish', 'de': 'sphinx.search.de.SearchGerman', 'en': SearchEnglish, @@ -186,9 +186,9 @@ class WordCollector(nodes.NodeVisitor): def __init__(self, document: nodes.document, lang: SearchLanguage) -> None: super().__init__(document) - self.found_words: List[str] = [] - self.found_titles: List[Tuple[str, str]] = [] - self.found_title_words: List[str] = [] + self.found_words: list[str] = [] + self.found_titles: list[tuple[str, str]] = [] + self.found_title_words: list[str] = [] self.lang = lang def is_meta_keywords(self, node: Element) -> bool: @@ -238,19 +238,19 @@ class IndexBuilder: 'pickle': pickle } - def __init__(self, env: BuildEnvironment, lang: str, options: Dict, scoring: str) -> None: + def __init__(self, env: BuildEnvironment, lang: str, options: dict, scoring: str) -> None: self.env = env - self._titles: Dict[str, str] = {} # docname -> title - self._filenames: Dict[str, str] = {} # docname -> filename - self._mapping: Dict[str, Set[str]] = {} # stemmed word -> set(docname) + self._titles: dict[str, str] = {} # docname -> title + self._filenames: dict[str, str] = {} # docname -> filename + self._mapping: dict[str, set[str]] = {} # stemmed word -> set(docname) # stemmed words in titles -> set(docname) - self._title_mapping: Dict[str, Set[str]] = {} - self._all_titles: Dict[str, List[Tuple[str, str]]] = {} # docname -> all titles - self._index_entries: Dict[str, List[Tuple[str, str, str]]] = {} # docname -> index entry - self._stem_cache: Dict[str, str] = {} # word -> stemmed word - self._objtypes: Dict[Tuple[str, str], int] = {} # objtype -> index + self._title_mapping: dict[str, set[str]] = {} + self._all_titles: dict[str, list[tuple[str, str]]] = {} # docname -> all titles + self._index_entries: dict[str, list[tuple[str, str, str]]] = {} # docname -> index entry + self._stem_cache: dict[str, str] = {} # word -> stemmed word + self._objtypes: dict[tuple[str, str], int] = {} # objtype -> index # objtype index -> (domain, type, objname (localized)) - self._objnames: Dict[int, Tuple[str, str, str]] = {} + self._objnames: dict[int, tuple[str, str, str]] = {} # add language-specific SearchLanguage instance lang_class = languages.get(lang) @@ -262,7 +262,7 @@ class IndexBuilder: self.lang: SearchLanguage = SearchEnglish(options) elif isinstance(lang_class, str): module, classname = lang_class.rsplit('.', 1) - lang_class: Type[SearchLanguage] = getattr(import_module(module), classname) # type: ignore[no-redef] + lang_class: type[SearchLanguage] = getattr(import_module(module), classname) # type: ignore[no-redef] self.lang = lang_class(options) # type: ignore[operator] else: # it's directly a class (e.g. added by app.add_search_language) @@ -299,7 +299,7 @@ class IndexBuilder: for doc, titleid in doc_tuples: self._all_titles[index2fn[doc]].append((title, titleid)) - def load_terms(mapping: Dict[str, Any]) -> Dict[str, Set[str]]: + def load_terms(mapping: dict[str, Any]) -> dict[str, set[str]]: rv = {} for k, v in mapping.items(): if isinstance(v, int): @@ -322,9 +322,9 @@ class IndexBuilder: format = self.formats[format] format.dump(self.freeze(), stream) - def get_objects(self, fn2index: Dict[str, int] - ) -> Dict[str, List[Tuple[int, int, int, str, str]]]: - rv: Dict[str, List[Tuple[int, int, int, str, str]]] = {} + def get_objects(self, fn2index: dict[str, int] + ) -> dict[str, list[tuple[int, int, int, str, str]]]: + rv: dict[str, list[tuple[int, int, int, str, str]]] = {} otypes = self._objtypes onames = self._objnames for domainname, domain in sorted(self.env.domains.items()): @@ -359,8 +359,8 @@ class IndexBuilder: plist.append((fn2index[docname], typeindex, prio, shortanchor, name)) return rv - def get_terms(self, fn2index: Dict) -> Tuple[Dict[str, List[str]], Dict[str, List[str]]]: - rvs: Tuple[Dict[str, List[str]], Dict[str, List[str]]] = ({}, {}) + def get_terms(self, fn2index: dict) -> tuple[dict[str, list[str]], dict[str, list[str]]]: + rvs: tuple[dict[str, list[str]], dict[str, list[str]]] = ({}, {}) for rv, mapping in zip(rvs, (self._mapping, self._title_mapping)): for k, v in mapping.items(): if len(v) == 1: @@ -371,7 +371,7 @@ class IndexBuilder: rv[k] = sorted([fn2index[fn] for fn in v if fn in fn2index]) return rvs - def freeze(self) -> Dict[str, Any]: + def freeze(self) -> dict[str, Any]: """Create a usable data structure for serializing.""" docnames, titles = zip(*sorted(self._titles.items())) filenames = [self._filenames.get(docname) for docname in docnames] @@ -382,12 +382,12 @@ class IndexBuilder: objtypes = {v: k[0] + ':' + k[1] for (k, v) in self._objtypes.items()} objnames = self._objnames - alltitles: Dict[str, List[Tuple[int, str]]] = {} + alltitles: dict[str, list[tuple[int, str]]] = {} for docname, titlelist in self._all_titles.items(): for title, titleid in titlelist: alltitles.setdefault(title, []).append((fn2index[docname], titleid)) - index_entries: Dict[str, List[Tuple[int, str]]] = {} + index_entries: dict[str, list[tuple[int, str]]] = {} for docname, entries in self._index_entries.items(): for entry, entry_id, main_entry in entries: index_entries.setdefault(entry.lower(), []).append((fn2index[docname], entry_id)) @@ -398,7 +398,7 @@ class IndexBuilder: alltitles=alltitles, indexentries=index_entries) def label(self) -> str: - return "%s (code: %s)" % (self.lang.language_name, self.lang.lang) + return f"{self.lang.language_name} (code: {self.lang.lang})" def prune(self, docnames: Iterable[str]) -> None: """Remove data for all docnames not in the list.""" @@ -454,7 +454,7 @@ class IndexBuilder: self._mapping.setdefault(stemmed_word, set()).add(docname) # find explicit entries within index directives - _index_entries: Set[Tuple[str, str, str]] = set() + _index_entries: set[tuple[str, str, str]] = set() for node in doctree.findall(addnodes.index): for entry_type, value, tid, main, *index_key in node['entries']: tid = tid or '' @@ -485,7 +485,7 @@ class IndexBuilder: self._index_entries[docname] = sorted(_index_entries) - def context_for_searchtool(self) -> Dict[str, Any]: + def context_for_searchtool(self) -> dict[str, Any]: if self.lang.js_splitter_code: js_splitter_code = self.lang.js_splitter_code else: @@ -498,7 +498,7 @@ class IndexBuilder: 'search_word_splitter_code': js_splitter_code, } - def get_js_stemmer_rawcodes(self) -> List[str]: + def get_js_stemmer_rawcodes(self) -> list[str]: """Returns a list of non-minified stemmer JS files to copy.""" if self.lang.js_stemmer_rawcode: return [ @@ -508,7 +508,7 @@ class IndexBuilder: else: return [] - def get_js_stemmer_rawcode(self) -> Optional[str]: + def get_js_stemmer_rawcode(self) -> str | None: return None def get_js_stemmer_code(self) -> str: diff --git a/sphinx/search/da.py b/sphinx/search/da.py index 28ecfec2c..73afd0902 100644 --- a/sphinx/search/da.py +++ b/sphinx/search/da.py @@ -113,7 +113,7 @@ class SearchDanish(SearchLanguage): js_stemmer_rawcode = 'danish-stemmer.js' stopwords = danish_stopwords - def init(self, options: Dict) -> None: + def init(self, options: dict) -> None: self.stemmer = snowballstemmer.stemmer('danish') def stem(self, word: str) -> str: diff --git a/sphinx/search/de.py b/sphinx/search/de.py index 279b2bf31..a10c0fc63 100644 --- a/sphinx/search/de.py +++ b/sphinx/search/de.py @@ -296,7 +296,7 @@ class SearchGerman(SearchLanguage): js_stemmer_rawcode = 'german-stemmer.js' stopwords = german_stopwords - def init(self, options: Dict) -> None: + def init(self, options: dict) -> None: self.stemmer = snowballstemmer.stemmer('german') def stem(self, word: str) -> str: diff --git a/sphinx/search/en.py b/sphinx/search/en.py index a55f0221d..5f6b89368 100644 --- a/sphinx/search/en.py +++ b/sphinx/search/en.py @@ -213,7 +213,7 @@ class SearchEnglish(SearchLanguage): js_stemmer_code = js_porter_stemmer stopwords = english_stopwords - def init(self, options: Dict) -> None: + def init(self, options: dict) -> None: self.stemmer = snowballstemmer.stemmer('porter') def stem(self, word: str) -> str: diff --git a/sphinx/search/es.py b/sphinx/search/es.py index 0ed9a20ae..201778ce6 100644 --- a/sphinx/search/es.py +++ b/sphinx/search/es.py @@ -356,7 +356,7 @@ class SearchSpanish(SearchLanguage): js_stemmer_rawcode = 'spanish-stemmer.js' stopwords = spanish_stopwords - def init(self, options: Dict) -> None: + def init(self, options: dict) -> None: self.stemmer = snowballstemmer.stemmer('spanish') def stem(self, word: str) -> str: diff --git a/sphinx/search/fi.py b/sphinx/search/fi.py index 52c1137b4..1f3c37115 100644 --- a/sphinx/search/fi.py +++ b/sphinx/search/fi.py @@ -106,7 +106,7 @@ class SearchFinnish(SearchLanguage): js_stemmer_rawcode = 'finnish-stemmer.js' stopwords = finnish_stopwords - def init(self, options: Dict) -> None: + def init(self, options: dict) -> None: self.stemmer = snowballstemmer.stemmer('finnish') def stem(self, word: str) -> str: diff --git a/sphinx/search/fr.py b/sphinx/search/fr.py index 5550816c2..6003ada3f 100644 --- a/sphinx/search/fr.py +++ b/sphinx/search/fr.py @@ -192,7 +192,7 @@ class SearchFrench(SearchLanguage): js_stemmer_rawcode = 'french-stemmer.js' stopwords = french_stopwords - def init(self, options: Dict) -> None: + def init(self, options: dict) -> None: self.stemmer = snowballstemmer.stemmer('french') def stem(self, word: str) -> str: diff --git a/sphinx/search/hu.py b/sphinx/search/hu.py index 77de918ab..0950115a7 100644 --- a/sphinx/search/hu.py +++ b/sphinx/search/hu.py @@ -219,7 +219,7 @@ class SearchHungarian(SearchLanguage): js_stemmer_rawcode = 'hungarian-stemmer.js' stopwords = hungarian_stopwords - def init(self, options: Dict) -> None: + def init(self, options: dict) -> None: self.stemmer = snowballstemmer.stemmer('hungarian') def stem(self, word: str) -> str: diff --git a/sphinx/search/it.py b/sphinx/search/it.py index 55e2f01e9..2f6cde8d2 100644 --- a/sphinx/search/it.py +++ b/sphinx/search/it.py @@ -309,7 +309,7 @@ class SearchItalian(SearchLanguage): js_stemmer_rawcode = 'italian-stemmer.js' stopwords = italian_stopwords - def init(self, options: Dict) -> None: + def init(self, options: dict) -> None: self.stemmer = snowballstemmer.stemmer('italian') def stem(self, word: str) -> str: diff --git a/sphinx/search/ja.py b/sphinx/search/ja.py index c69eccc8c..c35126a0b 100644 --- a/sphinx/search/ja.py +++ b/sphinx/search/ja.py @@ -33,10 +33,10 @@ from sphinx.util import import_object class BaseSplitter: - def __init__(self, options: Dict) -> None: + def __init__(self, options: dict) -> None: self.options = options - def split(self, input: str) -> List[str]: + def split(self, input: str) -> list[str]: """ :param str input: :return: @@ -46,7 +46,7 @@ class BaseSplitter: class MecabSplitter(BaseSplitter): - def __init__(self, options: Dict) -> None: + def __init__(self, options: dict) -> None: super().__init__(options) self.ctypes_libmecab: Any = None self.ctypes_mecab: Any = None @@ -56,7 +56,7 @@ class MecabSplitter(BaseSplitter): self.init_native(options) self.dict_encode = options.get('dic_enc', 'utf-8') - def split(self, input: str) -> List[str]: + def split(self, input: str) -> list[str]: if native_module: result = self.native.parse(input) else: @@ -64,14 +64,14 @@ class MecabSplitter(BaseSplitter): self.ctypes_mecab, input.encode(self.dict_encode)) return result.split(' ') - def init_native(self, options: Dict) -> None: + def init_native(self, options: dict) -> None: param = '-Owakati' dict = options.get('dict') if dict: param += ' -d %s' % dict self.native = MeCab.Tagger(param) - def init_ctypes(self, options: Dict) -> None: + def init_ctypes(self, options: dict) -> None: import ctypes.util lib = options.get('lib') @@ -115,7 +115,7 @@ MeCabBinder = MecabSplitter # keep backward compatibility until Sphinx-1.6 class JanomeSplitter(BaseSplitter): - def __init__(self, options: Dict) -> None: + def __init__(self, options: dict) -> None: super().__init__(options) self.user_dict = options.get('user_dic') self.user_dict_enc = options.get('user_dic_enc', 'utf8') @@ -126,7 +126,7 @@ class JanomeSplitter(BaseSplitter): raise RuntimeError('Janome is not available') self.tokenizer = janome.tokenizer.Tokenizer(udic=self.user_dict, udic_enc=self.user_dict_enc) - def split(self, input: str) -> List[str]: + def split(self, input: str) -> list[str]: result = ' '.join(token.surface for token in self.tokenizer.tokenize(input)) return result.split(' ') @@ -409,13 +409,13 @@ class DefaultSplitter(BaseSplitter): return 'O' # ts_ - def ts_(self, dict: Dict[str, int], key: str) -> int: + def ts_(self, dict: dict[str, int], key: str) -> int: if key in dict: return dict[key] return 0 # segment - def split(self, input: str) -> List[str]: + def split(self, input: str) -> list[str]: if not input: return [] @@ -518,7 +518,7 @@ class SearchJapanese(SearchLanguage): lang = 'ja' language_name = 'Japanese' - def init(self, options: Dict) -> None: + def init(self, options: dict) -> None: dotted_path = options.get('type', 'sphinx.search.ja.DefaultSplitter') try: self.splitter = import_object(dotted_path)(options) @@ -526,7 +526,7 @@ class SearchJapanese(SearchLanguage): raise ExtensionError("Splitter module %r can't be imported" % dotted_path) from exc - def split(self, input: str) -> List[str]: + def split(self, input: str) -> list[str]: return self.splitter.split(input) def word_filter(self, stemmed_word: str) -> bool: diff --git a/sphinx/search/nl.py b/sphinx/search/nl.py index 38d890c6d..6ab629c8f 100644 --- a/sphinx/search/nl.py +++ b/sphinx/search/nl.py @@ -120,7 +120,7 @@ class SearchDutch(SearchLanguage): js_stemmer_rawcode = 'dutch-stemmer.js' stopwords = dutch_stopwords - def init(self, options: Dict) -> None: + def init(self, options: dict) -> None: self.stemmer = snowballstemmer.stemmer('dutch') def stem(self, word: str) -> str: diff --git a/sphinx/search/no.py b/sphinx/search/no.py index 669c1cbf1..1ca031d66 100644 --- a/sphinx/search/no.py +++ b/sphinx/search/no.py @@ -195,7 +195,7 @@ class SearchNorwegian(SearchLanguage): js_stemmer_rawcode = 'norwegian-stemmer.js' stopwords = norwegian_stopwords - def init(self, options: Dict) -> None: + def init(self, options: dict) -> None: self.stemmer = snowballstemmer.stemmer('norwegian') def stem(self, word: str) -> str: diff --git a/sphinx/search/pt.py b/sphinx/search/pt.py index 2abe7966e..6caa5d7e6 100644 --- a/sphinx/search/pt.py +++ b/sphinx/search/pt.py @@ -254,7 +254,7 @@ class SearchPortuguese(SearchLanguage): js_stemmer_rawcode = 'portuguese-stemmer.js' stopwords = portuguese_stopwords - def init(self, options: Dict) -> None: + def init(self, options: dict) -> None: self.stemmer = snowballstemmer.stemmer('portuguese') def stem(self, word: str) -> str: diff --git a/sphinx/search/ro.py b/sphinx/search/ro.py index 7ae421f2d..28714aeba 100644 --- a/sphinx/search/ro.py +++ b/sphinx/search/ro.py @@ -13,9 +13,9 @@ class SearchRomanian(SearchLanguage): lang = 'ro' language_name = 'Romanian' js_stemmer_rawcode = 'romanian-stemmer.js' - stopwords: Set[str] = set() + stopwords: set[str] = set() - def init(self, options: Dict) -> None: + def init(self, options: dict) -> None: self.stemmer = snowballstemmer.stemmer('romanian') def stem(self, word: str) -> str: diff --git a/sphinx/search/ru.py b/sphinx/search/ru.py index 4c04259f7..67d1a74e7 100644 --- a/sphinx/search/ru.py +++ b/sphinx/search/ru.py @@ -244,7 +244,7 @@ class SearchRussian(SearchLanguage): js_stemmer_rawcode = 'russian-stemmer.js' stopwords = russian_stopwords - def init(self, options: Dict) -> None: + def init(self, options: dict) -> None: self.stemmer = snowballstemmer.stemmer('russian') def stem(self, word: str) -> str: diff --git a/sphinx/search/sv.py b/sphinx/search/sv.py index c5ab947fa..81282d375 100644 --- a/sphinx/search/sv.py +++ b/sphinx/search/sv.py @@ -133,7 +133,7 @@ class SearchSwedish(SearchLanguage): js_stemmer_rawcode = 'swedish-stemmer.js' stopwords = swedish_stopwords - def init(self, options: Dict) -> None: + def init(self, options: dict) -> None: self.stemmer = snowballstemmer.stemmer('swedish') def stem(self, word: str) -> str: diff --git a/sphinx/search/tr.py b/sphinx/search/tr.py index 00e1e93fc..6a7fd7097 100644 --- a/sphinx/search/tr.py +++ b/sphinx/search/tr.py @@ -13,9 +13,9 @@ class SearchTurkish(SearchLanguage): lang = 'tr' language_name = 'Turkish' js_stemmer_rawcode = 'turkish-stemmer.js' - stopwords: Set[str] = set() + stopwords: set[str] = set() - def init(self, options: Dict) -> None: + def init(self, options: dict) -> None: self.stemmer = snowballstemmer.stemmer('turkish') def stem(self, word: str) -> str: diff --git a/sphinx/search/zh.py b/sphinx/search/zh.py index 8d9132280..93bc0c8ac 100644 --- a/sphinx/search/zh.py +++ b/sphinx/search/zh.py @@ -225,9 +225,9 @@ class SearchChinese(SearchLanguage): js_stemmer_code = js_porter_stemmer stopwords = english_stopwords latin1_letters = re.compile(r'[a-zA-Z0-9_]+') - latin_terms: List[str] = [] + latin_terms: list[str] = [] - def init(self, options: Dict) -> None: + def init(self, options: dict) -> None: if JIEBA: dict_path = options.get('dict') if dict_path and os.path.isfile(dict_path): @@ -235,8 +235,8 @@ class SearchChinese(SearchLanguage): self.stemmer = snowballstemmer.stemmer('english') - def split(self, input: str) -> List[str]: - chinese: List[str] = [] + def split(self, input: str) -> list[str]: + chinese: list[str] = [] if JIEBA: chinese = list(jieba.cut_for_search(input)) diff --git a/sphinx/testing/comparer.py b/sphinx/testing/comparer.py index 8b2ec8892..4ea57a575 100644 --- a/sphinx/testing/comparer.py +++ b/sphinx/testing/comparer.py @@ -36,7 +36,7 @@ class PathComparer: return self.path.as_posix() def __repr__(self) -> str: - return "<{0.__class__.__name__}: '{0}'>".format(self) + return f"<{self.__class__.__name__}: '{self}'>" def __eq__(self, other: str | pathlib.Path) -> bool: # type: ignore return not bool(self.ldiff(other)) diff --git a/sphinx/testing/fixtures.py b/sphinx/testing/fixtures.py index 4f6b5de44..6af8e0223 100644 --- a/sphinx/testing/fixtures.py +++ b/sphinx/testing/fixtures.py @@ -215,7 +215,7 @@ def if_graphviz_found(app: SphinxTestApp) -> None: @pytest.fixture(scope='session') -def sphinx_test_tempdir(tmpdir_factory: Any) -> "util.path": +def sphinx_test_tempdir(tmpdir_factory: Any) -> util.path: """ Temporary directory wrapped with `path` class. """ @@ -224,7 +224,7 @@ def sphinx_test_tempdir(tmpdir_factory: Any) -> "util.path": @pytest.fixture -def tempdir(tmpdir: str) -> "util.path": +def tempdir(tmpdir: str) -> util.path: """ Temporary directory wrapped with `path` class. This fixture is for back-compatibility with old test implementation. diff --git a/sphinx/testing/path.py b/sphinx/testing/path.py index 9c03132de..8660e0a3c 100644 --- a/sphinx/testing/path.py +++ b/sphinx/testing/path.py @@ -26,7 +26,7 @@ class path(str): """ @property - def parent(self) -> "path": + def parent(self) -> path: """ The name of the directory the file or directory is in. """ @@ -35,7 +35,7 @@ class path(str): def basename(self) -> str: return os.path.basename(self) - def abspath(self) -> "path": + def abspath(self) -> path: """ Returns the absolute path. """ @@ -195,7 +195,7 @@ class path(str): """ os.makedirs(self, mode, exist_ok=exist_ok) - def joinpath(self, *args: Any) -> "path": + def joinpath(self, *args: Any) -> path: """ Joins the path with the argument given and returns the result. """ @@ -207,4 +207,4 @@ class path(str): __div__ = __truediv__ = joinpath def __repr__(self) -> str: - return '%s(%s)' % (self.__class__.__name__, super().__repr__()) + return f'{self.__class__.__name__}({super().__repr__()})' diff --git a/sphinx/testing/util.py b/sphinx/testing/util.py index 4e99c50ef..79d1390aa 100644 --- a/sphinx/testing/util.py +++ b/sphinx/testing/util.py @@ -26,17 +26,17 @@ __all__ = [ def assert_re_search(regex: re.Pattern, text: str, flags: int = 0) -> None: if not re.search(regex, text, flags): - raise AssertionError('%r did not match %r' % (regex, text)) + raise AssertionError(f'{regex!r} did not match {text!r}') def assert_not_re_search(regex: re.Pattern, text: str, flags: int = 0) -> None: if re.search(regex, text, flags): - raise AssertionError('%r did match %r' % (regex, text)) + raise AssertionError(f'{regex!r} did match {text!r}') def assert_startswith(thing: str, prefix: str) -> None: if not thing.startswith(prefix): - raise AssertionError('%r does not start with %r' % (thing, prefix)) + raise AssertionError(f'{thing!r} does not start with {prefix!r}') def assert_node(node: Node, cls: Any = None, xpath: str = "", **kwargs: Any) -> None: @@ -61,10 +61,10 @@ def assert_node(node: Node, cls: Any = None, xpath: str = "", **kwargs: Any) -> path = xpath + "[%d]" % i assert_node(node[i], nodecls, xpath=path, **kwargs) elif isinstance(cls, str): - assert node == cls, 'The node %r is not %r: %r' % (xpath, cls, node) + assert node == cls, f'The node {xpath!r} is not {cls!r}: {node!r}' else: assert isinstance(node, cls), \ - 'The node%s is not subclass of %r: %r' % (xpath, cls, node) + f'The node{xpath} is not subclass of {cls!r}: {node!r}' if kwargs: assert isinstance(node, nodes.Element), \ @@ -72,9 +72,9 @@ def assert_node(node: Node, cls: Any = None, xpath: str = "", **kwargs: Any) -> for key, value in kwargs.items(): assert key in node, \ - 'The node%s does not have %r attribute: %r' % (xpath, key, node) + f'The node{xpath} does not have {key!r} attribute: {node!r}' assert node[key] == value, \ - 'The node%s[%s] is not %r: %r' % (xpath, key, value, node[key]) + f'The node{xpath}[{key}] is not {value!r}: {node[key]!r}' def etree_parse(path: str) -> Any: @@ -154,7 +154,7 @@ class SphinxTestApp(application.Sphinx): delattr(nodes.GenericNodeVisitor, 'depart_' + method[6:]) def __repr__(self) -> str: - return '<%s buildername=%r>' % (self.__class__.__name__, self.builder.name) + return f'<{self.__class__.__name__} buildername={self.builder.name!r}>' class SphinxTestAppWrapperForSkipBuilding: diff --git a/sphinx/theming.py b/sphinx/theming.py index 96526a8b6..506fffc76 100644 --- a/sphinx/theming.py +++ b/sphinx/theming.py @@ -50,7 +50,7 @@ class Theme: This class supports both theme directory and theme archive (zipped theme).""" - def __init__(self, name: str, theme_path: str, factory: "HTMLThemeFactory") -> None: + def __init__(self, name: str, theme_path: str, factory: HTMLThemeFactory) -> None: self.name = name self.base = None self.rootdir = None @@ -150,7 +150,7 @@ def is_archived_theme(filename: str) -> bool: class HTMLThemeFactory: """A factory class for HTML Themes.""" - def __init__(self, app: "Sphinx") -> None: + def __init__(self, app: Sphinx) -> None: self.app = app self.themes = app.registry.html_themes self.load_builtin_themes() diff --git a/sphinx/transforms/__init__.py b/sphinx/transforms/__init__.py index a9011dbcb..3bb1d7b2e 100644 --- a/sphinx/transforms/__init__.py +++ b/sphinx/transforms/__init__.py @@ -4,7 +4,7 @@ from __future__ import annotations import re import unicodedata -from typing import TYPE_CHECKING, Any, Generator, Optional, cast +from typing import TYPE_CHECKING, Any, Generator, cast from docutils import nodes from docutils.nodes import Element # noqa: F401 (used for type comments only) @@ -46,12 +46,12 @@ class SphinxTransform(Transform): """ @property - def app(self) -> "Sphinx": + def app(self) -> Sphinx: """Reference to the :class:`.Sphinx` object.""" return self.env.app @property - def env(self) -> "BuildEnvironment": + def env(self) -> BuildEnvironment: """Reference to the :class:`.BuildEnvironment` object.""" return self.document.settings.env @@ -67,9 +67,9 @@ class SphinxTransformer(Transformer): """ document: nodes.document - env: Optional["BuildEnvironment"] = None + env: BuildEnvironment | None = None - def set_environment(self, env: "BuildEnvironment") -> None: + def set_environment(self, env: BuildEnvironment) -> None: self.env = env def apply_transforms(self) -> None: @@ -395,7 +395,7 @@ class GlossarySorter(SphinxTransform): ) -def setup(app: "Sphinx") -> dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_transform(ApplySourceWorkaround) app.add_transform(ExtraTranslatableNodes) app.add_transform(DefaultSubstitutions) diff --git a/sphinx/transforms/i18n.py b/sphinx/transforms/i18n.py index 145eb9cbb..d54a6ac1d 100644 --- a/sphinx/transforms/i18n.py +++ b/sphinx/transforms/i18n.py @@ -39,7 +39,7 @@ EXCLUDED_PENDING_XREF_ATTRIBUTES = ('refexplicit',) N = TypeVar('N', bound=nodes.Node) -def publish_msgstr(app: "Sphinx", source: str, source_path: str, source_line: int, +def publish_msgstr(app: Sphinx, source: str, source_path: str, source_line: int, config: Config, settings: Any) -> Element: """Publish msgstr (single line) into docutils document @@ -64,7 +64,7 @@ def publish_msgstr(app: "Sphinx", source: str, source_path: str, source_line: in parser = app.registry.create_source_parser(app, filetype) doc = reader.read( source=StringInput(source=source, - source_path="%s:%s:<translated>" % (source_path, source_line)), + source_path=f"{source_path}:{source_line}:<translated>"), parser=parser, settings=settings, ) @@ -516,7 +516,7 @@ class RemoveTranslatableInline(SphinxTransform): inline.parent += inline.children -def setup(app: "Sphinx") -> dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_transform(PreserveTranslatableMessages) app.add_transform(Locale) app.add_transform(RemoveTranslatableInline) diff --git a/sphinx/transforms/post_transforms/__init__.py b/sphinx/transforms/post_transforms/__init__.py index 07e734dcb..3df68b684 100644 --- a/sphinx/transforms/post_transforms/__init__.py +++ b/sphinx/transforms/post_transforms/__init__.py @@ -142,14 +142,14 @@ class ReferencesResolver(SphinxPostTransform): res = domain.resolve_xref(self.env, refdoc, self.app.builder, role, target, node, contnode) if res and len(res) > 0 and isinstance(res[0], nodes.Element): - results.append(('%s:%s' % (domain.name, role), res)) + results.append((f'{domain.name}:{role}', res)) # now, see how many matches we got... if not results: return None if len(results) > 1: def stringify(name: str, node: Element) -> str: reftitle = node.get('reftitle', node.astext()) - return ':%s:`%s`' % (name, reftitle) + return f':{name}:`{reftitle}`' candidates = ' or '.join(stringify(name, role) for name, role in results) logger.warning(__('more than one target found for \'any\' cross-' 'reference %r: could be %s'), target, candidates, @@ -170,7 +170,7 @@ class ReferencesResolver(SphinxPostTransform): warn = node.get('refwarn') if self.config.nitpicky: warn = True - dtype = '%s:%s' % (domain.name, typ) if domain else typ + dtype = f'{domain.name}:{typ}' if domain else typ if self.config.nitpick_ignore: if (dtype, target) in self.config.nitpick_ignore: warn = False diff --git a/sphinx/transforms/references.py b/sphinx/transforms/references.py index 49b8d2f8c..5de3a9515 100644 --- a/sphinx/transforms/references.py +++ b/sphinx/transforms/references.py @@ -36,7 +36,7 @@ class SphinxDomains(SphinxTransform): domain.process_doc(self.env, self.env.docname, self.document) -def setup(app: "Sphinx") -> dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_transform(SphinxDanglingReferences) app.add_transform(SphinxDomains) diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py index 32e0229d1..d1fa7734f 100644 --- a/sphinx/util/__init__.py +++ b/sphinx/util/__init__.py @@ -15,7 +15,7 @@ from datetime import datetime from importlib import import_module from os import path from time import mktime, strptime -from typing import IO, TYPE_CHECKING, Any, Callable, Generator, Iterable, Optional, TypeVar +from typing import IO, TYPE_CHECKING, Any, Callable, Generator, Iterable, TypeVar from urllib.parse import parse_qsl, quote_plus, urlencode, urlsplit, urlunsplit from sphinx.deprecation import RemovedInSphinx70Warning @@ -119,7 +119,7 @@ class FilenameUniqDict(dict): i = 0 while uniquename in self._existing: i += 1 - uniquename = '%s%s%s' % (base, i, ext) + uniquename = f'{base}{i}{ext}' self[newfile] = ({docname}, uniquename) self._existing.add(uniquename) return uniquename @@ -183,7 +183,7 @@ class DownloadFiles(dict): def add_file(self, docname: str, filename: str) -> str: if filename not in self: digest = md5(filename.encode()).hexdigest() - dest = '%s/%s' % (digest, os.path.basename(filename)) + dest = f'{digest}/{os.path.basename(filename)}' self[filename] = (set(), dest) self[filename][0].add(docname) @@ -212,7 +212,7 @@ _DEBUG_HEADER = '''\ ''' -def save_traceback(app: Optional["Sphinx"]) -> str: +def save_traceback(app: Sphinx | None) -> str: """Save the current exception's traceback in a temporary file.""" import platform @@ -342,7 +342,7 @@ def split_into(n: int, type: str, value: str) -> list[str]: """Split an index entry into a given number of parts at semicolons.""" parts = [x.strip() for x in value.split(';', n - 1)] if sum(1 for part in parts if part) < n: - raise ValueError('invalid %s index entry %r' % (type, value)) + raise ValueError(f'invalid {type} index entry {value!r}') return parts @@ -362,7 +362,7 @@ def split_index_msg(type: str, value: str) -> list[str]: elif type == 'seealso': result = split_into(2, 'see', value) else: - raise ValueError('invalid %s index entry %r' % (type, value)) + raise ValueError(f'invalid {type} index entry {value!r}') return result @@ -451,7 +451,7 @@ def display_chunk(chunk: Any) -> str: if isinstance(chunk, (list, tuple)): if len(chunk) == 1: return str(chunk[0]) - return '%s .. %s' % (chunk[0], chunk[-1]) + return f'{chunk[0]} .. {chunk[-1]}' return str(chunk) @@ -569,5 +569,4 @@ def xmlname_checker() -> re.Pattern: start_chars_regex = convert(name_start_chars) name_chars_regex = convert(name_chars) - return re.compile('(%s)(%s|%s)*' % ( - start_chars_regex, start_chars_regex, name_chars_regex)) + return re.compile(f'({start_chars_regex})({start_chars_regex}|{name_chars_regex})*') diff --git a/sphinx/util/cfamily.py b/sphinx/util/cfamily.py index 282499d70..e5337b0c2 100644 --- a/sphinx/util/cfamily.py +++ b/sphinx/util/cfamily.py @@ -4,7 +4,7 @@ from __future__ import annotations import re from copy import deepcopy -from typing import Any, Callable, Optional +from typing import Any, Callable from docutils import nodes from docutils.nodes import TextElement @@ -135,7 +135,7 @@ class ASTCPPAttribute(ASTAttribute): class ASTGnuAttribute(ASTBaseBase): - def __init__(self, name: str, args: Optional["ASTBaseParenExprList"]) -> None: + def __init__(self, name: str, args: ASTBaseParenExprList | None) -> None: self.name = name self.args = args @@ -201,7 +201,7 @@ class ASTAttributeList(ASTBaseBase): def __len__(self) -> int: return len(self.attrs) - def __add__(self, other: "ASTAttributeList") -> "ASTAttributeList": + def __add__(self, other: ASTAttributeList) -> ASTAttributeList: return ASTAttributeList(self.attrs + other.attrs) def _stringify(self, transform: StringifyTransform) -> str: @@ -237,7 +237,7 @@ class DefinitionError(Exception): class BaseParser: def __init__(self, definition: str, *, location: nodes.Node | tuple[str, int] | str, - config: "Config") -> None: + config: Config) -> None: self.definition = definition.strip() self.location = location # for warnings self.config = config @@ -280,7 +280,7 @@ class BaseParser: def status(self, msg: str) -> None: # for debugging indicator = '-' * self.pos + '^' - print("%s\n%s\n%s" % (msg, self.definition, indicator)) + print(f"{msg}\n{self.definition}\n{indicator}") def fail(self, msg: str) -> None: errors = [] diff --git a/sphinx/util/docfields.py b/sphinx/util/docfields.py index d997b0f43..299fd1fbb 100644 --- a/sphinx/util/docfields.py +++ b/sphinx/util/docfields.py @@ -235,7 +235,7 @@ class DocFieldTransformer: """ typemap: dict[str, tuple[Field, bool]] - def __init__(self, directive: "ObjectDescription") -> None: + def __init__(self, directive: ObjectDescription) -> None: self.directive = directive self.typemap = directive.get_field_type_map() diff --git a/sphinx/util/docutils.py b/sphinx/util/docutils.py index e012470c7..66670d764 100644 --- a/sphinx/util/docutils.py +++ b/sphinx/util/docutils.py @@ -277,7 +277,7 @@ class sphinx_domains(CustomReSTDispatcher): """Monkey-patch directive and role dispatch, so that domain-specific markup takes precedence. """ - def __init__(self, env: "BuildEnvironment") -> None: + def __init__(self, env: BuildEnvironment) -> None: self.env = env super().__init__() @@ -340,7 +340,7 @@ class WarningStream: class LoggingReporter(Reporter): @classmethod - def from_reporter(cls, reporter: Reporter) -> "LoggingReporter": + def from_reporter(cls, reporter: Reporter) -> LoggingReporter: """Create an instance of LoggingReporter from other reporter object.""" return cls(reporter.source, reporter.report_level, reporter.halt_level, reporter.debug_flag, reporter.error_handler) @@ -413,12 +413,12 @@ class SphinxDirective(Directive): """ @property - def env(self) -> "BuildEnvironment": + def env(self) -> BuildEnvironment: """Reference to the :class:`.BuildEnvironment` object.""" return self.state.document.settings.env @property - def config(self) -> "Config": + def config(self) -> Config: """Reference to the :class:`.Config` object.""" return self.env.config @@ -479,12 +479,12 @@ class SphinxRole: raise NotImplementedError @property - def env(self) -> "BuildEnvironment": + def env(self) -> BuildEnvironment: """Reference to the :class:`.BuildEnvironment` object.""" return self.inliner.document.settings.env @property - def config(self) -> "Config": + def config(self) -> Config: """Reference to the :class:`.Config` object.""" return self.env.config @@ -547,7 +547,7 @@ class SphinxTranslator(nodes.NodeVisitor): This class is strongly coupled with Sphinx. """ - def __init__(self, document: nodes.document, builder: "Builder") -> None: + def __init__(self, document: nodes.document, builder: Builder) -> None: super().__init__(document) self.builder = builder self.config = builder.config @@ -593,7 +593,7 @@ class SphinxTranslator(nodes.NodeVisitor): # cache a vanilla instance of nodes.document # Used in new_document() function -__document_cache__: tuple["Values", Reporter] +__document_cache__: tuple[Values, Reporter] def new_document(source_path: str, settings: Any = None) -> nodes.document: diff --git a/sphinx/util/fileutil.py b/sphinx/util/fileutil.py index c9c50e84a..03928710e 100644 --- a/sphinx/util/fileutil.py +++ b/sphinx/util/fileutil.py @@ -4,7 +4,7 @@ from __future__ import annotations import os import posixpath -from typing import TYPE_CHECKING, Callable, Optional +from typing import TYPE_CHECKING, Callable from docutils.utils import relative_path @@ -17,7 +17,7 @@ if TYPE_CHECKING: def copy_asset_file(source: str, destination: str, context: dict | None = None, - renderer: Optional["BaseRenderer"] = None) -> None: + renderer: BaseRenderer | None = None) -> None: """Copy an asset file to destination. On copying, it expands the template variables if context argument is given and @@ -50,7 +50,7 @@ def copy_asset_file(source: str, destination: str, def copy_asset(source: str, destination: str, excluded: PathMatcher = lambda path: False, - context: dict | None = None, renderer: Optional["BaseRenderer"] = None, + context: dict | None = None, renderer: BaseRenderer | None = None, onerror: Callable[[str, Exception], None] | None = None) -> None: """Copy asset files to destination recursively. diff --git a/sphinx/util/i18n.py b/sphinx/util/i18n.py index 1219269bf..b20fc016b 100644 --- a/sphinx/util/i18n.py +++ b/sphinx/util/i18n.py @@ -233,7 +233,7 @@ def format_date( return "".join(result) -def get_image_filename_for_language(filename: str, env: "BuildEnvironment") -> str: +def get_image_filename_for_language(filename: str, env: BuildEnvironment) -> str: filename_format = env.config.figure_language_filename d = {} d['root'], d['ext'] = path.splitext(filename) @@ -253,7 +253,7 @@ def get_image_filename_for_language(filename: str, env: "BuildEnvironment") -> s raise SphinxError('Invalid figure_language_filename: %r' % exc) from exc -def search_image_for_language(filename: str, env: "BuildEnvironment") -> str: +def search_image_for_language(filename: str, env: BuildEnvironment) -> str: translated = get_image_filename_for_language(filename, env) _, abspath = env.relfn2path(translated) if path.exists(abspath): diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py index 4fb2503ee..10673ca57 100644 --- a/sphinx/util/inspect.py +++ b/sphinx/util/inspect.py @@ -397,7 +397,7 @@ def object_description(object: Any) -> str: return "frozenset({%s})" % ", ".join(object_description(x) for x in sorted_values) elif isinstance(object, enum.Enum): - return "%s.%s" % (object.__class__.__name__, object.name) + return f"{object.__class__.__name__}.{object.name}" try: s = repr(object) @@ -690,13 +690,14 @@ def stringify_signature(sig: inspect.Signature, show_annotation: bool = True, # PEP-570: Separator for Positional Only Parameter: / args.append('/') + concatenated_args = ', '.join(args) if (sig.return_annotation is Parameter.empty or show_annotation is False or show_return_annotation is False): - return '(%s)' % ', '.join(args) + return f'({concatenated_args})' else: annotation = stringify_annotation(sig.return_annotation, mode) - return '(%s) -> %s' % (', '.join(args), annotation) + return f'({concatenated_args}) -> {annotation}' def signature_from_str(signature: str) -> inspect.Signature: diff --git a/sphinx/util/inventory.py b/sphinx/util/inventory.py index 91369f559..422b99868 100644 --- a/sphinx/util/inventory.py +++ b/sphinx/util/inventory.py @@ -138,7 +138,7 @@ class InventoryFile: return invdata @classmethod - def dump(cls, filename: str, env: "BuildEnvironment", builder: "Builder") -> None: + def dump(cls, filename: str, env: BuildEnvironment, builder: Builder) -> None: def escape(string: str) -> str: return re.sub("\\s+", " ", string) diff --git a/sphinx/util/jsdump.py b/sphinx/util/jsdump.py index 5d8a32781..e2014716b 100644 --- a/sphinx/util/jsdump.py +++ b/sphinx/util/jsdump.py @@ -42,13 +42,13 @@ def encode_string(s: str) -> str: except KeyError: n = ord(s) if n < 0x10000: - return '\\u%04x' % (n,) + return f'\\u{n:04x}' else: # surrogate pair n -= 0x10000 s1 = 0xd800 | ((n >> 10) & 0x3ff) s2 = 0xdc00 | (n & 0x3ff) - return '\\u%04x\\u%04x' % (s1, s2) + return f'\\u{s1:04x}\\u{s2:04x}' return '"' + str(ESCAPE_ASCII.sub(replace, s)) + '"' @@ -89,10 +89,9 @@ def dumps(obj: Any, key: bool = False) -> str: elif isinstance(obj, (int, float)): return str(obj) elif isinstance(obj, dict): - return '{%s}' % ','.join(sorted('%s:%s' % ( - dumps(key, True), - dumps(value) - ) for key, value in obj.items())) + return '{%s}' % ','.join( + sorted(f'{dumps(key, True)}:{dumps(value)}' for key, value in obj.items()) + ) elif isinstance(obj, set): return '[%s]' % ','.join(sorted(dumps(x) for x in obj)) elif isinstance(obj, (tuple, list)): diff --git a/sphinx/util/logging.py b/sphinx/util/logging.py index 9fad129d7..b2ff96854 100644 --- a/sphinx/util/logging.py +++ b/sphinx/util/logging.py @@ -49,7 +49,7 @@ COLOR_MAP = defaultdict(lambda: 'blue', }) -def getLogger(name: str) -> "SphinxLoggerAdapter": +def getLogger(name: str) -> SphinxLoggerAdapter: """Get logger wrapped by :class:`sphinx.util.logging.SphinxLoggerAdapter`. Sphinx logger always uses ``sphinx.*`` namespace to be independent from @@ -92,7 +92,7 @@ class SphinxLogRecord(logging.LogRecord): message = super().getMessage() location = getattr(self, 'location', None) if location: - message = '%s: %s%s' % (location, self.prefix, message) + message = f'{location}: {self.prefix}{message}' elif self.prefix not in message: message = self.prefix + message @@ -381,7 +381,7 @@ def is_suppressed_warning(type: str, subtype: str, suppress_warnings: list[str]) class WarningSuppressor(logging.Filter): """Filter logs by `suppress_warnings`.""" - def __init__(self, app: "Sphinx") -> None: + def __init__(self, app: Sphinx) -> None: self.app = app super().__init__() @@ -405,7 +405,7 @@ class WarningSuppressor(logging.Filter): class WarningIsErrorFilter(logging.Filter): """Raise exception if warning emitted.""" - def __init__(self, app: "Sphinx") -> None: + def __init__(self, app: Sphinx) -> None: self.app = app super().__init__() @@ -481,7 +481,7 @@ class SphinxLogRecordTranslator(logging.Filter): """ LogRecordClass: type[logging.LogRecord] - def __init__(self, app: "Sphinx") -> None: + def __init__(self, app: Sphinx) -> None: self.app = app super().__init__() @@ -494,7 +494,7 @@ class SphinxLogRecordTranslator(logging.Filter): if isinstance(location, tuple): docname, lineno = location if docname and lineno: - record.location = '%s:%s' % (self.app.env.doc2path(docname), lineno) + record.location = f'{self.app.env.doc2path(docname)}:{lineno}' elif docname: record.location = '%s' % self.app.env.doc2path(docname) else: @@ -522,7 +522,7 @@ def get_node_location(node: Node) -> str | None: if source: source = abspath(source) if source and line: - return "%s:%s" % (source, line) + return f"{source}:{line}" elif source: return "%s:" % source elif line: @@ -565,14 +565,14 @@ class SafeEncodingWriter: class LastMessagesWriter: """Stream writer storing last 10 messages in memory to save trackback""" - def __init__(self, app: "Sphinx", stream: IO) -> None: + def __init__(self, app: Sphinx, stream: IO) -> None: self.app = app def write(self, data: str) -> None: self.app.messagelog.append(data) -def setup(app: "Sphinx", status: IO, warning: IO) -> None: +def setup(app: Sphinx, status: IO, warning: IO) -> None: """Setup root logger for Sphinx""" logger = logging.getLogger(NAMESPACE) logger.setLevel(logging.DEBUG) diff --git a/sphinx/util/matching.py b/sphinx/util/matching.py index 5350b623a..00d988c3a 100644 --- a/sphinx/util/matching.py +++ b/sphinx/util/matching.py @@ -49,7 +49,7 @@ def _translate_pattern(pat: str) -> str: stuff = '^/' + stuff[1:] elif stuff[0] == '^': stuff = '\\' + stuff - res = '%s[%s]' % (res, stuff) + res = f'{res}[{stuff}]' else: res += re.escape(c) return res + '$' diff --git a/sphinx/util/math.py b/sphinx/util/math.py index cd06dc249..f5b565020 100644 --- a/sphinx/util/math.py +++ b/sphinx/util/math.py @@ -11,7 +11,7 @@ def get_node_equation_number(writer: HTML5Translator, node: nodes.math_block) -> if writer.builder.config.math_numfig and writer.builder.config.numfig: figtype = 'displaymath' if writer.builder.name == 'singlehtml': - key = "%s/%s" % (writer.docnames[-1], figtype) + key = f"{writer.docnames[-1]}/{figtype}" else: key = figtype @@ -54,4 +54,5 @@ def wrap_displaymath(text: str, label: str | None, numbering: bool) -> str: for part in parts: equations.append('%s\\\\\n' % part.strip()) - return '%s\n%s%s' % (begin, ''.join(equations), end) + concatenated_equations = ''.join(equations) + return f'{begin}\n{concatenated_equations}{end}' diff --git a/sphinx/util/nodes.py b/sphinx/util/nodes.py index bd1c924e2..201b547d9 100644 --- a/sphinx/util/nodes.py +++ b/sphinx/util/nodes.py @@ -295,7 +295,7 @@ def get_prev_node(node: Node) -> Node | None: def traverse_translatable_index( doctree: Element -) -> Iterable[tuple[Element, list["IndexEntry"]]]: +) -> Iterable[tuple[Element, list[IndexEntry]]]: """Traverse translatable index node from a document tree.""" matcher = NodeMatcher(addnodes.index, inline=False) for node in doctree.findall(matcher): # type: addnodes.index @@ -387,7 +387,7 @@ def process_index_entry(entry: str, targetid: str return indexentries -def inline_all_toctrees(builder: "Builder", docnameset: set[str], docname: str, +def inline_all_toctrees(builder: Builder, docnameset: set[str], docname: str, tree: nodes.document, colorfunc: Callable, traversed: list[str] ) -> nodes.document: """Inline all toctrees in the *tree*. @@ -494,7 +494,7 @@ _non_id_translate_digraphs = { } -def make_id(env: "BuildEnvironment", document: nodes.document, +def make_id(env: BuildEnvironment, document: nodes.document, prefix: str = '', term: str | None = None) -> str: """Generate an appropriate node_id for given *prefix* and *term*.""" node_id = None @@ -530,7 +530,7 @@ def find_pending_xref_condition(node: addnodes.pending_xref, condition: str return None -def make_refnode(builder: "Builder", fromdocname: str, todocname: str, targetid: str, +def make_refnode(builder: Builder, fromdocname: str, todocname: str, targetid: str, child: Node | list[Node], title: str | None = None ) -> nodes.reference: """Shortcut to create a reference node.""" @@ -588,7 +588,7 @@ def is_smartquotable(node: Node) -> bool: return True -def process_only_nodes(document: Node, tags: "Tags") -> None: +def process_only_nodes(document: Node, tags: Tags) -> None: """Filter ``only`` nodes which do not match *tags*.""" for node in document.findall(addnodes.only): try: diff --git a/sphinx/util/osutil.py b/sphinx/util/osutil.py index d495876cf..f6b13c899 100644 --- a/sphinx/util/osutil.py +++ b/sphinx/util/osutil.py @@ -196,7 +196,7 @@ class FileAvoidWrite: with open(self._path, 'w', encoding='utf-8') as f: f.write(buf) - def __enter__(self) -> "FileAvoidWrite": + def __enter__(self) -> FileAvoidWrite: return self def __exit__( diff --git a/sphinx/util/rst.py b/sphinx/util/rst.py index f8c944590..7a1538325 100644 --- a/sphinx/util/rst.py +++ b/sphinx/util/rst.py @@ -57,7 +57,7 @@ def heading(env: Environment, text: str, level: int = 1) -> str: assert level <= 3 width = textwidth(text, WIDECHARS[env.language]) sectioning_char = SECTIONING_CHARS[level - 1] - return '%s\n%s' % (text, sectioning_char * width) + return f'{text}\n{sectioning_char * width}' @contextmanager diff --git a/sphinx/util/tags.py b/sphinx/util/tags.py index b44d97b3b..a9f767672 100644 --- a/sphinx/util/tags.py +++ b/sphinx/util/tags.py @@ -32,7 +32,7 @@ class BooleanParser(Parser): node = self.parse_expression() self.stream.expect('rparen') else: - self.fail("unexpected token '%s'" % (token,), token.lineno) + self.fail(f"unexpected token '{token}'", token.lineno) return node diff --git a/sphinx/util/typing.py b/sphinx/util/typing.py index 5c44eed01..53f32ed46 100644 --- a/sphinx/util/typing.py +++ b/sphinx/util/typing.py @@ -116,15 +116,15 @@ def restify(cls: type | None, mode: str = 'fully-qualified-except-typing') -> st elif isinstance(cls, str): return cls elif ismockmodule(cls): - return ':py:class:`%s%s`' % (modprefix, cls.__name__) + return f':py:class:`{modprefix}{cls.__name__}`' elif ismock(cls): - return ':py:class:`%s%s.%s`' % (modprefix, cls.__module__, cls.__name__) + return f':py:class:`{modprefix}{cls.__module__}.{cls.__name__}`' elif is_invalid_builtin_class(cls): - return ':py:class:`%s%s`' % (modprefix, INVALID_BUILTIN_CLASSES[cls]) + return f':py:class:`{modprefix}{INVALID_BUILTIN_CLASSES[cls]}`' elif inspect.isNewType(cls): if sys.version_info[:2] >= (3, 10): # newtypes have correct module info since Python 3.10+ - return ':py:class:`%s%s.%s`' % (modprefix, cls.__module__, cls.__name__) + return f':py:class:`{modprefix}{cls.__module__}.{cls.__name__}`' else: return ':py:class:`%s`' % cls.__name__ elif UnionType and isinstance(cls, UnionType): @@ -135,10 +135,8 @@ def restify(cls: type | None, mode: str = 'fully-qualified-except-typing') -> st return ' | '.join(restify(a, mode) for a in cls.__args__) elif cls.__module__ in ('__builtin__', 'builtins'): if hasattr(cls, '__args__'): - return ':py:class:`%s`\\ [%s]' % ( - cls.__name__, - ', '.join(restify(arg, mode) for arg in cls.__args__), - ) + concatenated_args = ', '.join(restify(arg, mode) for arg in cls.__args__) + return fr':py:class:`{cls.__name__}`\ [{concatenated_args}]' else: return ':py:class:`%s`' % cls.__name__ elif (inspect.isgenericalias(cls) @@ -178,7 +176,7 @@ def restify(cls: type | None, mode: str = 'fully-qualified-except-typing') -> st elif (cls.__module__ == 'typing' and cls._name == 'Callable'): # type: ignore[attr-defined] args = ', '.join(restify(a, mode) for a in cls.__args__[:-1]) - text += r"\ [[%s], %s]" % (args, restify(cls.__args__[-1], mode)) + text += fr"\ [[{args}], {restify(cls.__args__[-1], mode)}]" elif cls.__module__ == 'typing' and getattr(origin, '_name', None) == 'Literal': text += r"\ [%s]" % ', '.join(repr(a) for a in cls.__args__) elif cls.__args__: @@ -192,17 +190,17 @@ def restify(cls: type | None, mode: str = 'fully-qualified-except-typing') -> st return f':py:obj:`~{cls.__module__}.{cls.__name__}`' elif hasattr(cls, '__qualname__'): if cls.__module__ == 'typing': - return ':py:class:`~%s.%s`' % (cls.__module__, cls.__qualname__) + return f':py:class:`~{cls.__module__}.{cls.__qualname__}`' else: - return ':py:class:`%s%s.%s`' % (modprefix, cls.__module__, cls.__qualname__) + return f':py:class:`{modprefix}{cls.__module__}.{cls.__qualname__}`' elif isinstance(cls, ForwardRef): return ':py:class:`%s`' % cls.__forward_arg__ else: # not a class (ex. TypeVar) if cls.__module__ == 'typing': - return ':py:obj:`~%s.%s`' % (cls.__module__, cls.__name__) + return f':py:obj:`~{cls.__module__}.{cls.__name__}`' else: - return ':py:obj:`%s%s.%s`' % (modprefix, cls.__module__, cls.__name__) + return f':py:obj:`{modprefix}{cls.__module__}.{cls.__name__}`' except (AttributeError, TypeError): return inspect.object_description(cls) @@ -243,7 +241,7 @@ def stringify(annotation: Any, mode: str = 'fully-qualified-except-typing') -> s elif inspect.isNewType(annotation): if sys.version_info[:2] >= (3, 10): # newtypes have correct module info since Python 3.10+ - return modprefix + '%s.%s' % (annotation.__module__, annotation.__name__) + return modprefix + f'{annotation.__module__}.{annotation.__name__}' else: return annotation.__name__ elif not annotation: @@ -253,7 +251,7 @@ def stringify(annotation: Any, mode: str = 'fully-qualified-except-typing') -> s elif ismockmodule(annotation): return modprefix + annotation.__name__ elif ismock(annotation): - return modprefix + '%s.%s' % (annotation.__module__, annotation.__name__) + return modprefix + f'{annotation.__module__}.{annotation.__name__}' elif is_invalid_builtin_class(annotation): return modprefix + INVALID_BUILTIN_CLASSES[annotation] elif str(annotation).startswith('typing.Annotated'): # for py310+ @@ -307,26 +305,25 @@ def stringify(annotation: Any, mode: str = 'fully-qualified-except-typing') -> s if len(annotation.__args__) > 1 and annotation.__args__[-1] is NoneType: if len(annotation.__args__) > 2: args = ', '.join(stringify(a, mode) for a in annotation.__args__[:-1]) - return '%sOptional[%sUnion[%s]]' % (modprefix, modprefix, args) + return f'{modprefix}Optional[{modprefix}Union[{args}]]' else: - return '%sOptional[%s]' % (modprefix, - stringify(annotation.__args__[0], mode)) + return f'{modprefix}Optional[{stringify(annotation.__args__[0], mode)}]' else: args = ', '.join(stringify(a, mode) for a in annotation.__args__) - return '%sUnion[%s]' % (modprefix, args) + return f'{modprefix}Union[{args}]' elif qualname == 'types.Union': if len(annotation.__args__) > 1 and None in annotation.__args__: args = ' | '.join(stringify(a) for a in annotation.__args__ if a) - return '%sOptional[%s]' % (modprefix, args) + return f'{modprefix}Optional[{args}]' else: return ' | '.join(stringify(a) for a in annotation.__args__) elif qualname == 'Callable': args = ', '.join(stringify(a, mode) for a in annotation.__args__[:-1]) returns = stringify(annotation.__args__[-1], mode) - return '%s%s[[%s], %s]' % (modprefix, qualname, args, returns) + return f'{modprefix}{qualname}[[{args}], {returns}]' elif qualname == 'Literal': args = ', '.join(repr(a) for a in annotation.__args__) - return '%s%s[%s]' % (modprefix, qualname, args) + return f'{modprefix}{qualname}[{args}]' elif str(annotation).startswith('typing.Annotated'): # for py39+ return stringify(annotation.__args__[0], mode) elif all(is_system_TypeVar(a) for a in annotation.__args__): @@ -334,6 +331,6 @@ def stringify(annotation: Any, mode: str = 'fully-qualified-except-typing') -> s return modprefix + qualname else: args = ', '.join(stringify(a, mode) for a in annotation.__args__) - return '%s%s[%s]' % (modprefix, qualname, args) + return f'{modprefix}{qualname}[{args}]' return modprefix + qualname diff --git a/sphinx/versioning.py b/sphinx/versioning.py index 41db32e4e..86cd1e43f 100644 --- a/sphinx/versioning.py +++ b/sphinx/versioning.py @@ -166,7 +166,7 @@ class UIDTransform(SphinxTransform): list(merge_doctrees(old_doctree, self.document, env.versioning_condition)) -def setup(app: "Sphinx") -> dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_transform(UIDTransform) return { diff --git a/sphinx/writers/_html4.py b/sphinx/writers/_html4.py index 56ad5b554..7aec4c892 100644 --- a/sphinx/writers/_html4.py +++ b/sphinx/writers/_html4.py @@ -36,7 +36,7 @@ def multiply_length(length: str, scale: int) -> str: else: amount, unit = matched.groups() result = float(amount) * scale / 100 - return "%s%s" % (int(result), unit) + return f"{int(result)}{unit}" # RemovedInSphinx70Warning @@ -45,7 +45,7 @@ class HTML4Translator(SphinxTranslator, BaseTranslator): Our custom HTML translator. """ - builder: "StandaloneHTMLBuilder" + builder: StandaloneHTMLBuilder def __init__(self, document: nodes.document, builder: Builder) -> None: super().__init__(document, builder) @@ -261,7 +261,7 @@ class HTML4Translator(SphinxTranslator, BaseTranslator): elif isinstance(node.parent, nodes.section): if self.builder.name == 'singlehtml': docname = self.docnames[-1] - anchorname = "%s/#%s" % (docname, node.parent['ids'][0]) + anchorname = f"{docname}/#{node.parent['ids'][0]}" if anchorname not in self.builder.secnumbers: anchorname = "%s/" % docname # try first heading which has no anchor else: @@ -283,7 +283,7 @@ class HTML4Translator(SphinxTranslator, BaseTranslator): def add_fignumber(self, node: Element) -> None: def append_fignumber(figtype: str, figure_id: str) -> None: if self.builder.name == 'singlehtml': - key = "%s/%s" % (self.docnames[-1], figtype) + key = f"{self.docnames[-1]}/{figtype}" else: key = figtype @@ -402,7 +402,7 @@ class HTML4Translator(SphinxTranslator, BaseTranslator): elif close_tag.startswith('</a></h'): self.body.append('</a><a class="headerlink" href="#%s" ' % node.parent['ids'][0] + - 'title="%s">%s' % ( + 'title="{}">{}'.format( _('Permalink to this heading'), self.config.html_permalinks_icon)) elif isinstance(node.parent, nodes.table): diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py index e425d1238..faa8d8ad8 100644 --- a/sphinx/writers/html.py +++ b/sphinx/writers/html.py @@ -26,7 +26,7 @@ class HTMLWriter(Writer): # override embed-stylesheet default value to False. settings_default_overrides = {"embed_stylesheet": False} - def __init__(self, builder: "StandaloneHTMLBuilder") -> None: + def __init__(self, builder: StandaloneHTMLBuilder) -> None: super().__init__() self.builder = builder diff --git a/sphinx/writers/html5.py b/sphinx/writers/html5.py index e07e86ab4..edf8bdc23 100644 --- a/sphinx/writers/html5.py +++ b/sphinx/writers/html5.py @@ -39,7 +39,7 @@ def multiply_length(length: str, scale: int) -> str: else: amount, unit = matched.groups() result = float(amount) * scale / 100 - return "%s%s" % (int(result), unit) + return f"{int(result)}{unit}" class HTML5Translator(SphinxTranslator, BaseTranslator): @@ -47,7 +47,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): Our custom HTML translator. """ - builder: "StandaloneHTMLBuilder" + builder: StandaloneHTMLBuilder # Override docutils.writers.html5_polyglot:HTMLTranslator # otherwise, nodes like <inline classes="s">...</inline> will be # converted to <s>...</s> by `visit_inline`. @@ -267,7 +267,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): if isinstance(node.parent, nodes.section): if self.builder.name == 'singlehtml': docname = self.docnames[-1] - anchorname = "%s/#%s" % (docname, node.parent['ids'][0]) + anchorname = "{}/#{}".format(docname, node.parent['ids'][0]) if anchorname not in self.builder.secnumbers: anchorname = "%s/" % docname # try first heading which has no anchor else: @@ -289,7 +289,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): def add_fignumber(self, node: Element) -> None: def append_fignumber(figtype: str, figure_id: str) -> None: if self.builder.name == 'singlehtml': - key = "%s/%s" % (self.docnames[-1], figtype) + key = f"{self.docnames[-1]}/{figtype}" else: key = figtype @@ -388,7 +388,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): elif close_tag.startswith('</a></h'): self.body.append('</a><a class="headerlink" href="#%s" ' % node.parent['ids'][0] + - 'title="%s">%s' % ( + 'title="{}">{}'.format( _('Permalink to this heading'), self.config.html_permalinks_icon)) elif isinstance(node.parent, nodes.table): diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index f5be84f76..c6c63828b 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -10,7 +10,7 @@ import re import warnings from collections import defaultdict from os import path -from typing import TYPE_CHECKING, Any, Iterable, Optional, cast +from typing import TYPE_CHECKING, Any, Iterable, cast from docutils import nodes, writers from docutils.nodes import Element, Node, Text @@ -78,7 +78,7 @@ class LaTeXWriter(writers.Writer): output = None - def __init__(self, builder: "LaTeXBuilder") -> None: + def __init__(self, builder: LaTeXBuilder) -> None: super().__init__() self.builder = builder self.theme: Theme = None @@ -173,7 +173,7 @@ class Table: if self.colwidths and 'colwidths-given' in self.classes: total = sum(self.colwidths) colspecs = [r'\X{%d}{%d}' % (width, total) for width in self.colwidths] - return '{%s%s%s}' % (_colsep, _colsep.join(colspecs), _colsep) + CR + return f'{{{_colsep}{_colsep.join(colspecs)}{_colsep}}}' + CR elif self.has_problematic: return r'{%s*{%d}{\X{1}{%d}%s}}' % (_colsep, self.colcount, self.colcount, _colsep) + CR @@ -199,7 +199,7 @@ class Table: def cell( self, row: int | None = None, col: int | None = None - ) -> Optional["TableCell"]: + ) -> TableCell | None: """Returns a cell object (i.e. rectangular area) containing given position. If no option arguments: ``row`` or ``col`` are given, the current position; @@ -279,19 +279,19 @@ def rstdim_to_latexdim(width_str: str, scale: int = 100) -> str: elif unit == "%": res = r"%.5f\linewidth" % (amount_float / 100.0) else: - res = "%.5f%s" % (amount_float, unit) + res = f"{amount_float:.5f}{unit}" return res class LaTeXTranslator(SphinxTranslator): - builder: "LaTeXBuilder" + builder: LaTeXBuilder secnumdepth = 2 # legacy sphinxhowto.cls uses this, whereas article.cls # default is originally 3. For book/report, 2 is already LaTeX default. ignore_missing_images = False - def __init__(self, document: nodes.document, builder: "LaTeXBuilder", - theme: "Theme") -> None: + def __init__(self, document: nodes.document, builder: LaTeXBuilder, + theme: Theme) -> None: super().__init__(document, builder) self.body: list[str] = [] self.theme = theme @@ -471,7 +471,7 @@ class LaTeXTranslator(SphinxTranslator): prefix = '' suffix = '' - return r'%s\renewcommand{%s}{%s}%s' % (prefix, command, definition, suffix) + CR + return fr'{prefix}\renewcommand{{{command}}}{{{definition}}}{suffix}' + CR def generate_indices(self) -> str: def generate(content: list[tuple[str, list[IndexEntry]]], collapsed: bool) -> None: @@ -499,7 +499,7 @@ class LaTeXTranslator(SphinxTranslator): if indices_config: for domain in self.builder.env.domains.values(): for indexcls in domain.indices: - indexname = '%s-%s' % (domain.name, indexcls.name) + indexname = f'{domain.name}-{indexcls.name}' if isinstance(indices_config, list): if indexname not in indices_config: continue @@ -634,10 +634,10 @@ class LaTeXTranslator(SphinxTranslator): short = ('[%s]' % self.escape(' '.join(clean_astext(node).split()))) try: - self.body.append(r'\%s%s{' % (self.sectionnames[self.sectionlevel], short)) + self.body.append(fr'\{self.sectionnames[self.sectionlevel]}{short}{{') except IndexError: # just use "subparagraph", it's not numbered anyway - self.body.append(r'\%s%s{' % (self.sectionnames[-1], short)) + self.body.append(fr'\{self.sectionnames[-1]}{short}{{') self.context.append('}' + CR + self.hypertarget_to(node.parent)) elif isinstance(parent, nodes.topic): self.body.append(r'\sphinxstyletopictitle{') @@ -1325,9 +1325,9 @@ class LaTeXTranslator(SphinxTranslator): if self.in_title and base: # Lowercase tokens forcely because some fncychap themes capitalize # the options of \sphinxincludegraphics unexpectedly (ex. WIDTH=...). - cmd = r'\lowercase{\sphinxincludegraphics%s}{{%s}%s}' % (options, base, ext) + cmd = fr'\lowercase{{\sphinxincludegraphics{options}}}{{{{{base}}}{ext}}}' else: - cmd = r'\sphinxincludegraphics%s{{%s}%s}' % (options, base, ext) + cmd = fr'\sphinxincludegraphics{options}{{{{{base}}}{ext}}}' # escape filepath for includegraphics, https://tex.stackexchange.com/a/202714/41112 if '#' in base: cmd = r'{\catcode`\#=12' + cmd + '}' @@ -1532,11 +1532,11 @@ class LaTeXTranslator(SphinxTranslator): try: p1, p2 = (escape(x) for x in split_into(2, 'single', string)) P1, P2 = style(p1), style(p2) - self.body.append(r'\index{%s@%s!%s@%s%s}' % (p1, P1, p2, P2, m)) + self.body.append(fr'\index{{{p1}@{P1}!{p2}@{P2}{m}}}') except ValueError: p = escape(split_into(1, 'single', string)[0]) P = style(p) - self.body.append(r'\index{%s@%s%s}' % (p, P, m)) + self.body.append(fr'\index{{{p}@{P}{m}}}') elif type == 'pair': p1, p2 = (escape(x) for x in split_into(2, 'pair', string)) P1, P2 = style(p1), style(p2) @@ -1555,11 +1555,11 @@ class LaTeXTranslator(SphinxTranslator): elif type == 'see': p1, p2 = (escape(x) for x in split_into(2, 'see', string)) P1 = style(p1) - self.body.append(r'\index{%s@%s|see{%s}}' % (p1, P1, p2)) + self.body.append(fr'\index{{{p1}@{P1}|see{{{p2}}}}}') elif type == 'seealso': p1, p2 = (escape(x) for x in split_into(2, 'seealso', string)) P1 = style(p1) - self.body.append(r'\index{%s@%s|see{%s}}' % (p1, P1, p2)) + self.body.append(fr'\index{{{p1}@{P1}|see{{{p2}}}}}') else: logger.warning(__('unknown index entry type %s found'), type) except ValueError as err: @@ -1653,7 +1653,7 @@ class LaTeXTranslator(SphinxTranslator): else: # old style format (cf. "Fig.%{number}") text = escape_abbr(title) % (r'\ref{%s}' % self.idescape(id)) - hyperref = r'\hyperref[%s]{%s}' % (self.idescape(id), text) + hyperref = fr'\hyperref[{self.idescape(id)}]{{{text}}}' self.body.append(hyperref) raise nodes.SkipNode @@ -1735,8 +1735,8 @@ class LaTeXTranslator(SphinxTranslator): def visit_citation(self, node: Element) -> None: label = cast(nodes.label, node[0]) - self.body.append(r'\bibitem[%s]{%s:%s}' % (self.encode(label.astext()), - node['docname'], node['ids'][0])) + self.body.append(fr'\bibitem[{self.encode(label.astext())}]' + fr'{{{node["docname"]}:{node["ids"][0]}}}') def depart_citation(self, node: Element) -> None: pass @@ -1745,7 +1745,7 @@ class LaTeXTranslator(SphinxTranslator): if self.in_title: pass else: - self.body.append(r'\sphinxcite{%s:%s}' % (node['docname'], node['refname'])) + self.body.append(fr'\sphinxcite{{{node["docname"]}:{node["refname"]}}}') raise nodes.SkipNode def depart_citation_reference(self, node: Element) -> None: @@ -2069,7 +2069,7 @@ class LaTeXTranslator(SphinxTranslator): def visit_math_block(self, node: Element) -> None: if node.get('label'): - label = "equation:%s:%s" % (node['docname'], node['label']) + label = f"equation:{node['docname']}:{node['label']}" else: label = None @@ -2084,7 +2084,7 @@ class LaTeXTranslator(SphinxTranslator): raise nodes.SkipNode def visit_math_reference(self, node: Element) -> None: - label = "equation:%s:%s" % (node['docname'], node['target']) + label = f"equation:{node['docname']}:{node['target']}" eqref_format = self.config.math_eqref_format if eqref_format: try: diff --git a/sphinx/writers/texinfo.py b/sphinx/writers/texinfo.py index 08d030443..33ae2574b 100644 --- a/sphinx/writers/texinfo.py +++ b/sphinx/writers/texinfo.py @@ -120,7 +120,7 @@ class TexinfoWriter(writers.Writer): visitor_attributes = ('output', 'fragment') - def __init__(self, builder: "TexinfoBuilder") -> None: + def __init__(self, builder: TexinfoBuilder) -> None: super().__init__() self.builder = builder @@ -136,7 +136,7 @@ class TexinfoWriter(writers.Writer): class TexinfoTranslator(SphinxTranslator): ignore_missing_images = False - builder: "TexinfoBuilder" + builder: TexinfoBuilder default_elements = { 'author': '', @@ -153,7 +153,7 @@ class TexinfoTranslator(SphinxTranslator): 'title': '', } - def __init__(self, document: nodes.document, builder: "TexinfoBuilder") -> None: + def __init__(self, document: nodes.document, builder: TexinfoBuilder) -> None: super().__init__(document, builder) self.init_settings() @@ -194,13 +194,13 @@ class TexinfoTranslator(SphinxTranslator): name, content = index pointers = tuple([name] + self.rellinks[name]) self.body.append('\n@node %s,%s,%s,%s\n' % pointers) - self.body.append('@unnumbered %s\n\n%s\n' % (name, content)) + self.body.append(f'@unnumbered {name}\n\n{content}\n') while self.referenced_ids: # handle xrefs with missing anchors r = self.referenced_ids.pop() if r not in self.written_ids: - self.body.append('@anchor{%s}@w{%s}\n' % (r, ' ' * 30)) + self.body.append('@anchor{{{}}}@w{{{}}}\n'.format(r, ' ' * 30)) self.ensure_eol() self.fragment = ''.join(self.body) self.elements['body'] = self.fragment @@ -383,9 +383,9 @@ class TexinfoTranslator(SphinxTranslator): def format_menu_entry(self, name: str, node_name: str, desc: str) -> str: if name == node_name: - s = '* %s:: ' % (name,) + s = f'* {name}:: ' else: - s = '* %s: %s. ' % (name, node_name) + s = f'* {name}: {node_name}. ' offset = max((24, (len(name) + 4) % 78)) wdesc = '\n'.join(' ' * offset + l for l in textwrap.wrap(desc, width=78 - offset)) @@ -460,7 +460,7 @@ class TexinfoTranslator(SphinxTranslator): if not entry[3]: continue name = self.escape_menu(entry[0]) - sid = self.get_short_id('%s:%s' % (entry[2], entry[3])) + sid = self.get_short_id(f'{entry[2]}:{entry[3]}') desc = self.escape_arg(entry[6]) me = self.format_menu_entry(name, sid, desc) ret.append(me) @@ -471,7 +471,7 @@ class TexinfoTranslator(SphinxTranslator): if indices_config: for domain in self.builder.env.domains.values(): for indexcls in domain.indices: - indexname = '%s-%s' % (domain.name, indexcls.name) + indexname = f'{domain.name}-{indexcls.name}' if isinstance(indices_config, list): if indexname not in indices_config: continue @@ -538,7 +538,7 @@ class TexinfoTranslator(SphinxTranslator): name = self.escape_menu(name) sid = self.get_short_id(id) if self.config.texinfo_cross_references: - self.body.append('@ref{%s,,%s}' % (sid, name)) + self.body.append(f'@ref{{{sid},,{name}}}') self.referenced_ids.add(sid) self.referenced_ids.add(self.escape_id(id)) else: @@ -696,7 +696,7 @@ class TexinfoTranslator(SphinxTranslator): if not name or name == uri: self.body.append('@email{%s}' % uri) else: - self.body.append('@email{%s,%s}' % (uri, name)) + self.body.append(f'@email{{{uri},{name}}}') elif uri.startswith('#'): # references to labels in the same document id = self.curfilestack[-1] + ':' + uri[1:] @@ -721,9 +721,9 @@ class TexinfoTranslator(SphinxTranslator): id = self.escape_id(id) name = self.escape_menu(name) if name == id: - self.body.append('@ref{%s,,,%s}' % (id, uri)) + self.body.append(f'@ref{{{id},,,{uri}}}') else: - self.body.append('@ref{%s,,%s,%s}' % (id, name, uri)) + self.body.append(f'@ref{{{id},,{name},{uri}}}') else: uri = self.escape_arg(uri) name = self.escape_arg(name) @@ -733,11 +733,11 @@ class TexinfoTranslator(SphinxTranslator): if not name or uri == name: self.body.append('@indicateurl{%s}' % uri) elif show_urls == 'inline': - self.body.append('@uref{%s,%s}' % (uri, name)) + self.body.append(f'@uref{{{uri},{name}}}') elif show_urls == 'no': - self.body.append('@uref{%s,,%s}' % (uri, name)) + self.body.append(f'@uref{{{uri},,{name}}}') else: - self.body.append('%s@footnote{%s}' % (name, uri)) + self.body.append(f'{name}@footnote{{{uri}}}') raise nodes.SkipNode def depart_reference(self, node: Element) -> None: @@ -1210,7 +1210,7 @@ class TexinfoTranslator(SphinxTranslator): width = self.tex_image_length(node.get('width', '')) height = self.tex_image_length(node.get('height', '')) alt = self.escape_arg(node.get('alt', '')) - filename = "%s-figures/%s" % (self.elements['filename'][:-5], name) # type: ignore + filename = f"{self.elements['filename'][:-5]}-figures/{name}" # type: ignore self.body.append('\n@image{%s,%s,%s,%s,%s}\n' % (filename, width, height, alt, ext[1:])) @@ -1405,7 +1405,7 @@ class TexinfoTranslator(SphinxTranslator): name = objtype # by convention, the deffn category should be capitalized like a title category = self.escape_arg(smart_capwords(name)) - self.body.append('\n%s {%s} ' % (self.at_deffnx, category)) + self.body.append(f'\n{self.at_deffnx} {{{category}}} ') self.at_deffnx = '@deffnx' self.desc_type_name: str | None = name diff --git a/sphinx/writers/text.py b/sphinx/writers/text.py index d437fb3d5..ded21fb2f 100644 --- a/sphinx/writers/text.py +++ b/sphinx/writers/text.py @@ -33,9 +33,7 @@ class Cell: self.row: int | None = None def __repr__(self) -> str: - return "<Cell {!r} {}v{}/{}>{}>".format( - self.text, self.row, self.rowspan, self.col, self.colspan - ) + return f"<Cell {self.text!r} {self.row}v{self.rowspan}/{self.col}>{self.colspan}>" def __hash__(self) -> int: return hash((self.col, self.row)) @@ -362,7 +360,7 @@ class TextWriter(writers.Writer): output: str = None - def __init__(self, builder: "TextBuilder") -> None: + def __init__(self, builder: TextBuilder) -> None: super().__init__() self.builder = builder @@ -373,9 +371,9 @@ class TextWriter(writers.Writer): class TextTranslator(SphinxTranslator): - builder: "TextBuilder" = None + builder: TextBuilder = None - def __init__(self, document: nodes.document, builder: "TextBuilder") -> None: + def __init__(self, document: nodes.document, builder: TextBuilder) -> None: super().__init__(document, builder) newlines = self.config.text_newlines diff --git a/tests/roots/test-ext-autodoc/target/TYPE_CHECKING.py b/tests/roots/test-ext-autodoc/target/TYPE_CHECKING.py index 9d42b3872..df30ab62c 100644 --- a/tests/roots/test-ext-autodoc/target/TYPE_CHECKING.py +++ b/tests/roots/test-ext-autodoc/target/TYPE_CHECKING.py @@ -7,4 +7,4 @@ if TYPE_CHECKING: class Foo: - attr1: "StringIO" + attr1: StringIO diff --git a/tests/roots/test-ext-autodoc/target/overload.py b/tests/roots/test-ext-autodoc/target/overload.py index 902f00915..4bcb6ea3c 100644 --- a/tests/roots/test-ext-autodoc/target/overload.py +++ b/tests/roots/test-ext-autodoc/target/overload.py @@ -9,7 +9,7 @@ def sum(x: int, y: int = 0) -> int: @overload -def sum(x: "float", y: "float" = 0.0) -> "float": +def sum(x: float, y: float = 0.0) -> float: ... @@ -31,7 +31,7 @@ class Math: ... @overload - def sum(self, x: "float", y: "float" = 0.0) -> "float": + def sum(self, x: float, y: float = 0.0) -> float: ... @overload @@ -47,11 +47,11 @@ class Foo: """docstring""" @overload - def __new__(cls, x: int, y: int) -> "Foo": + def __new__(cls, x: int, y: int) -> Foo: ... @overload - def __new__(cls, x: "str", y: "str") -> "Foo": + def __new__(cls, x: str, y: str) -> Foo: ... def __new__(cls, x, y): @@ -66,7 +66,7 @@ class Bar: ... @overload - def __init__(cls, x: "str", y: "str") -> "None": + def __init__(cls, x: str, y: str) -> None: ... def __init__(cls, x, y): @@ -79,7 +79,7 @@ class Meta(type): ... @overload - def __call__(cls, x: "str", y: "str") -> "Any": + def __call__(cls, x: str, y: str) -> Any: ... def __call__(cls, x, y): diff --git a/tests/roots/test-ext-autodoc/target/typehints.py b/tests/roots/test-ext-autodoc/target/typehints.py index de2f6d2a8..90715945f 100644 --- a/tests/roots/test-ext-autodoc/target/typehints.py +++ b/tests/roots/test-ext-autodoc/target/typehints.py @@ -56,12 +56,12 @@ class Math: return pathlib.PurePosixPath("/a/b/c") -def tuple_args(x: Tuple[int, Union[int, str]]) -> Tuple[int, int]: +def tuple_args(x: tuple[int, int | str]) -> tuple[int, int]: pass class NewAnnotation: - def __new__(cls, i: int) -> 'NewAnnotation': + def __new__(cls, i: int) -> NewAnnotation: pass diff --git a/tests/roots/test-ext-autosummary-filename-map/autosummary_dummy_module.py b/tests/roots/test-ext-autosummary-filename-map/autosummary_dummy_module.py index 9fb1256e6..b88e33520 100644 --- a/tests/roots/test-ext-autosummary-filename-map/autosummary_dummy_module.py +++ b/tests/roots/test-ext-autosummary-filename-map/autosummary_dummy_module.py @@ -19,5 +19,5 @@ class Foo: pass -def bar(x: Union[int, str], y: int = 1) -> None: +def bar(x: int | str, y: int = 1) -> None: pass diff --git a/tests/roots/test-ext-viewcode/conf.py b/tests/roots/test-ext-viewcode/conf.py index bee063988..5e07214fd 100644 --- a/tests/roots/test-ext-viewcode/conf.py +++ b/tests/roots/test-ext-viewcode/conf.py @@ -19,6 +19,6 @@ if 'test_linkcode' in tags: elif domain == "js": return "http://foobar/js/" + info['fullname'] elif domain in ("c", "cpp"): - return "http://foobar/%s/%s" % (domain, "".join(info['names'])) + return f"http://foobar/{domain}/{''.join(info['names'])}" else: raise AssertionError() diff --git a/tests/roots/test-ext-viewcode/spam/mod1.py b/tests/roots/test-ext-viewcode/spam/mod1.py index 22cc1a0de..a078328c2 100644 --- a/tests/roots/test-ext-viewcode/spam/mod1.py +++ b/tests/roots/test-ext-viewcode/spam/mod1.py @@ -16,13 +16,13 @@ def func1(a, b): @decorator -class Class1(object): +class Class1: """ this is Class1 """ -class Class3(object): +class Class3: """ this is Class3 """ diff --git a/tests/roots/test-ext-viewcode/spam/mod2.py b/tests/roots/test-ext-viewcode/spam/mod2.py index 92d196177..72cb08978 100644 --- a/tests/roots/test-ext-viewcode/spam/mod2.py +++ b/tests/roots/test-ext-viewcode/spam/mod2.py @@ -16,7 +16,7 @@ def func2(a, b): @decorator -class Class2(object): +class Class2: """ this is Class2 """ diff --git a/tests/test_build_html.py b/tests/test_build_html.py index d985aad76..5b27a4796 100644 --- a/tests/test_build_html.py +++ b/tests/test_build_html.py @@ -70,7 +70,7 @@ def tail_check(check): for node in nodes: if node.tail and rex.search(node.tail): return True - raise AssertionError('%r not found in tail of any nodes %s' % (check, nodes)) + raise AssertionError(f'{check!r} not found in tail of any nodes {nodes}') return checker diff --git a/tests/test_build_latex.py b/tests/test_build_latex.py index 96ba87243..a59e8525c 100644 --- a/tests/test_build_latex.py +++ b/tests/test_build_latex.py @@ -61,8 +61,8 @@ def compile_latex_document(app, filename='python.tex'): except CalledProcessError as exc: print(exc.stdout.decode('utf8')) print(exc.stderr.decode('utf8')) - raise AssertionError('%s exited with return code %s' % (app.config.latex_engine, - exc.returncode)) + raise AssertionError(f'{app.config.latex_engine} exited with ' + f'return code {exc.returncode}') def skip_if_requested(testfunc): diff --git a/tests/test_domain_cpp.py b/tests/test_domain_cpp.py index 8593c41f6..34d808a82 100644 --- a/tests/test_domain_cpp.py +++ b/tests/test_domain_cpp.py @@ -1199,7 +1199,7 @@ def test_domain_cpp_build_with_add_function_parentheses_is_True(app, status, war pattern = '<li><p>%s<a .*?><code .*?><span .*?>%s</span></code></a></p></li>' % spec res = re.search(pattern, text) if not res: - print("Pattern\n\t%s\nnot found in %s" % (pattern, file)) + print(f"Pattern\n\t{pattern}\nnot found in {file}") raise AssertionError() rolePatterns = [ ('', 'Sphinx'), @@ -1240,7 +1240,7 @@ def test_domain_cpp_build_with_add_function_parentheses_is_False(app, status, wa pattern = '<li><p>%s<a .*?><code .*?><span .*?>%s</span></code></a></p></li>' % spec res = re.search(pattern, text) if not res: - print("Pattern\n\t%s\nnot found in %s" % (pattern, file)) + print(f"Pattern\n\t{pattern}\nnot found in {file}") raise AssertionError() rolePatterns = [ ('', 'Sphinx'), @@ -1281,16 +1281,16 @@ def test_domain_cpp_build_xref_consistency(app, status, warning): output = (app.outdir / test).read_text(encoding='utf8') def classes(role, tag): - pattern = (r'{role}-role:.*?' - r'<(?P<tag>{tag}) .*?class=["\'](?P<classes>.*?)["\'].*?>' + pattern = (fr'{role}-role:.*?' + fr'<(?P<tag>{tag}) .*?class=["\'](?P<classes>.*?)["\'].*?>' r'.*' - r'</(?P=tag)>').format(role=role, tag=tag) + r'</(?P=tag)>') result = re.search(pattern, output) - expect = '''\ + expect = f'''\ Pattern for role `{role}` with tag `{tag}` \t{pattern} not found in `{test}` -'''.format(role=role, tag=tag, pattern=pattern, test=test) +''' assert result, expect return set(result.group('classes').split()) diff --git a/tests/test_ext_autodoc_configs.py b/tests/test_ext_autodoc_configs.py index 4f0d06bb4..7ce8ed3d6 100644 --- a/tests/test_ext_autodoc_configs.py +++ b/tests/test_ext_autodoc_configs.py @@ -779,8 +779,7 @@ def test_autodoc_typehints_signature(app): ' :module: target.typehints', '', '', - '.. py:function:: tuple_args(x: ~typing.Tuple[int, ~typing.Union[int, str]]) ' - '-> ~typing.Tuple[int, int]', + '.. py:function:: tuple_args(x: tuple[int, int | str]) -> tuple[int, int]', ' :module: target.typehints', '', ] @@ -965,10 +964,10 @@ def test_autodoc_typehints_description(app): assert ('target.typehints.tuple_args(x)\n' '\n' ' Parameters:\n' - ' **x** (*Tuple**[**int**, **Union**[**int**, **str**]**]*) --\n' + ' **x** (*tuple**[**int**, **int** | **str**]*) --\n' '\n' ' Return type:\n' - ' *Tuple*[int, int]\n' + ' tuple[int, int]\n' in context) # Overloads still get displayed in the signature @@ -1015,13 +1014,13 @@ def test_autodoc_typehints_description_no_undoc(app): 'target.typehints.tuple_args(x)\n' '\n' ' Parameters:\n' - ' **x** (*Tuple**[**int**, **Union**[**int**, **str**]**]*) -- arg\n' + ' **x** (*tuple**[**int**, **int** | **str**]*) -- arg\n' '\n' ' Returns:\n' ' another tuple\n' '\n' ' Return type:\n' - ' *Tuple*[int, int]\n' + ' tuple[int, int]\n' in context) @@ -1072,13 +1071,13 @@ def test_autodoc_typehints_description_no_undoc_doc_rtype(app): 'target.typehints.tuple_args(x)\n' '\n' ' Parameters:\n' - ' **x** (*Tuple**[**int**, **Union**[**int**, **str**]**]*) -- arg\n' + ' **x** (*tuple**[**int**, **int** | **str**]*) -- arg\n' '\n' ' Returns:\n' ' another tuple\n' '\n' ' Return type:\n' - ' *Tuple*[int, int]\n' + ' tuple[int, int]\n' '\n' 'target.typehints.Math.nothing(self)\n' '\n' @@ -1221,13 +1220,13 @@ def test_autodoc_typehints_both(app): ' Return type:\n' ' int\n' in context) - assert ('target.typehints.tuple_args(x: Tuple[int, Union[int, str]]) -> Tuple[int, int]\n' + assert ('target.typehints.tuple_args(x: tuple[int, int | str]) -> tuple[int, int]\n' '\n' ' Parameters:\n' - ' **x** (*Tuple**[**int**, **Union**[**int**, **str**]**]*) --\n' + ' **x** (*tuple**[**int**, **int** | **str**]*) --\n' '\n' ' Return type:\n' - ' *Tuple*[int, int]\n' + ' tuple[int, int]\n' in context) # Overloads still get displayed in the signature @@ -1527,8 +1526,7 @@ def test_autodoc_typehints_format_fully_qualified(app): ' :module: target.typehints', '', '', - '.. py:function:: tuple_args(x: typing.Tuple[int, typing.Union[int, str]]) ' - '-> typing.Tuple[int, int]', + '.. py:function:: tuple_args(x: tuple[int, int | str]) -> tuple[int, int]', ' :module: target.typehints', '', ] diff --git a/tests/test_ext_autosummary.py b/tests/test_ext_autosummary.py index 1b2c4d7a8..286a55b42 100644 --- a/tests/test_ext_autosummary.py +++ b/tests/test_ext_autosummary.py @@ -62,7 +62,7 @@ def test_mangle_signature(): if '::' in x] for inp, outp in TEST: res = mangle_signature(inp).strip().replace("\u00a0", " ") - assert res == outp, ("'%s' -> '%s' != '%s'" % (inp, res, outp)) + assert res == outp, (f"'{inp}' -> '{res}' != '{outp}'") def test_extract_summary(capsys): diff --git a/tests/test_ext_napoleon_docstring.py b/tests/test_ext_napoleon_docstring.py index 2919fa171..ee79cb92c 100644 --- a/tests/test_ext_napoleon_docstring.py +++ b/tests/test_ext_napoleon_docstring.py @@ -410,25 +410,24 @@ class GoogleDocstringTest(BaseDocstringTest): config = Config() for section, admonition in admonition_map.items(): # Multiline - actual = str(GoogleDocstring(("{}:\n" - " this is the first line\n" - "\n" - " and this is the second line\n" - ).format(section), config)) - expect = (".. {}::\n" + actual = str(GoogleDocstring(f"{section}:\n" + " this is the first line\n" + "\n" + " and this is the second line\n", + config)) + expect = (f".. {admonition}::\n" "\n" " this is the first line\n" " \n" " and this is the second line\n" - ).format(admonition) + ) self.assertEqual(expect, actual) # Single line - actual = str(GoogleDocstring(("{}:\n" - " this is a single line\n" - ).format(section), config)) - expect = (".. {}:: this is a single line\n" - ).format(admonition) + actual = str(GoogleDocstring(f"{section}:\n" + " this is a single line\n", + config)) + expect = f".. {admonition}:: this is a single line\n" self.assertEqual(expect, actual) def test_docstrings(self): @@ -1472,27 +1471,26 @@ class NumpyDocstringTest(BaseDocstringTest): config = Config() for section, admonition in admonition_map.items(): # Multiline - actual = str(NumpyDocstring(("{}\n" - "{}\n" - " this is the first line\n" - "\n" - " and this is the second line\n" - ).format(section, '-' * len(section)), config)) - expect = (".. {}::\n" + actual = str(NumpyDocstring(f"{section}\n" + f"{'-' * len(section)}\n" + " this is the first line\n" + "\n" + " and this is the second line\n", + config)) + expect = (f".. {admonition}::\n" "\n" " this is the first line\n" " \n" " and this is the second line\n" - ).format(admonition) + ) self.assertEqual(expect, actual) # Single line - actual = str(NumpyDocstring(("{}\n" - "{}\n" - " this is a single line\n" - ).format(section, '-' * len(section)), config)) - expect = (".. {}:: this is a single line\n" - ).format(admonition) + actual = str(NumpyDocstring(f"{section}\n" + f"{'-' * len(section)}\n" + f" this is a single line\n", + config)) + expect = f".. {admonition}:: this is a single line\n" self.assertEqual(expect, actual) def test_docstrings(self): diff --git a/tests/test_ext_viewcode.py b/tests/test_ext_viewcode.py index 6d443d1c6..ff53e5d37 100644 --- a/tests/test_ext_viewcode.py +++ b/tests/test_ext_viewcode.py @@ -36,8 +36,7 @@ def test_viewcode(app, status, warning): assert ('<div class="viewcode-block" id="Class1"><a class="viewcode-back" ' 'href="../../index.html#spam.Class1">[docs]</a>' '<span>@decorator</span>\n' - '<span>class</span> <span>Class1</span>' - '<span>(</span><span>object</span><span>):</span>\n' + '<span>class</span> <span>Class1</span><span>:</span>\n' '<span> </span><span>"""</span>\n' '<span> this is Class1</span>\n' '<span> """</span></div>\n') in result @@ -45,8 +44,7 @@ def test_viewcode(app, status, warning): assert ('<div class="viewcode-block" id="Class1"><a class="viewcode-back" ' 'href="../../index.html#spam.Class1">[docs]</a>' '<span>@decorator</span>\n' - '<span>class</span> <span>Class1</span>' - '<span>(</span><span>object</span><span>):</span>\n' + '<span>class</span> <span>Class1</span><span>:</span>\n' ' <span>"""</span>\n' '<span> this is Class1</span>\n' '<span> """</span></div>\n') in result diff --git a/tests/test_intl.py b/tests/test_intl.py index 07dfe8be3..3b04b293c 100644 --- a/tests/test_intl.py +++ b/tests/test_intl.py @@ -705,12 +705,12 @@ def test_html_index_entries(app): def wrap(tag, keyword): start_tag = "<%s[^>]*>" % tag end_tag = "</%s>" % tag - return r"%s\s*%s\s*%s" % (start_tag, keyword, end_tag) + return fr"{start_tag}\s*{keyword}\s*{end_tag}" def wrap_nest(parenttag, childtag, keyword): start_tag1 = "<%s[^>]*>" % parenttag start_tag2 = "<%s[^>]*>" % childtag - return r"%s\s*%s\s*%s" % (start_tag1, keyword, start_tag2) + return fr"{start_tag1}\s*{keyword}\s*{start_tag2}" expected_exprs = [ wrap('a', 'NEWSLETTER'), wrap('a', 'MAILING LIST'), diff --git a/utils/bump_version.py b/utils/bump_version.py index a76391d1c..9421475ec 100755 --- a/utils/bump_version.py +++ b/utils/bump_version.py @@ -107,7 +107,7 @@ class Changes: def finalize_release_date(self): release_date = datetime.now().strftime('%b %d, %Y') - heading = 'Release %s (released %s)' % (self.version, release_date) + heading = f'Release {self.version} (released {release_date})' with open(self.path, 'r+', encoding='utf-8') as f: f.readline() # skip first two lines @@ -125,9 +125,8 @@ class Changes: version = stringify_version(version_info) else: reltype = version_info[3] - version = '%s %s%s' % (stringify_version(version_info), - RELEASE_TYPE.get(reltype, reltype), - version_info[4] or '') + version = (f'{stringify_version(version_info)} ' + f'{RELEASE_TYPE.get(reltype, reltype)}{version_info[4] or ""}') heading = 'Release %s (in development)' % version with open(os.path.join(script_dir, 'CHANGES_template'), encoding='utf-8') as f: |