diff --git a/doc/conf.py b/doc/conf.py index 45089831f84..da7df38110e 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -158,7 +158,7 @@ def linkify_issues_in_changelog(app, docname, source): def linkify(match): url = 'https://github.com/sphinx-doc/sphinx/issues/' + match[1] - return '`{} <{}>`_'.format(match[0], url) + return f'`{match[0]} <{url}>`_' linkified_changelog = re.sub(r'(?:PR)?#([0-9]+)\b', linkify, changelog) diff --git a/doc/development/tutorials/examples/recipe.py b/doc/development/tutorials/examples/recipe.py index 8dc53fdd6dc..845628864e3 100644 --- a/doc/development/tutorials/examples/recipe.py +++ b/doc/development/tutorials/examples/recipe.py @@ -140,8 +140,8 @@ def resolve_xref(self, env, fromdocname, builder, typ, target, node, def add_recipe(self, signature, ingredients): """Add a new recipe to the domain.""" - name = '{}.{}'.format('recipe', signature) - anchor = 'recipe-{}'.format(signature) + name = f'recipe.{signature}' + anchor = f'recipe-{signature}' self.data['recipe_ingredients'][name] = ingredients # name, dispname, type, docname, anchor, priority diff --git a/doc/usage/extensions/example_google.py b/doc/usage/extensions/example_google.py index 6f82a2e5f3e..434fa3b67c3 100644 --- a/doc/usage/extensions/example_google.py +++ b/doc/usage/extensions/example_google.py @@ -142,8 +142,7 @@ def example_generator(n): [0, 1, 2, 3] """ - for i in range(n): - yield i + yield from range(n) class ExampleError(Exception): diff --git a/doc/usage/extensions/example_numpy.py b/doc/usage/extensions/example_numpy.py index 22595b4e807..2346b1ea91c 100644 --- a/doc/usage/extensions/example_numpy.py +++ b/doc/usage/extensions/example_numpy.py @@ -180,8 +180,7 @@ def example_generator(n): [0, 1, 2, 3] """ - for i in range(n): - yield i + yield from range(n) class ExampleError(Exception): diff --git a/sphinx/__init__.py b/sphinx/__init__.py index 17d8c971a3f..07c61917017 100644 --- a/sphinx/__init__.py +++ b/sphinx/__init__.py @@ -43,8 +43,7 @@ ret = subprocess.run( ['git', 'show', '-s', '--pretty=format:%h'], cwd=package_dir, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, + capture_output=True, encoding='ascii', ).stdout if ret: diff --git a/sphinx/addnodes.py b/sphinx/addnodes.py index fea9c0edd71..00042fee999 100644 --- a/sphinx/addnodes.py +++ b/sphinx/addnodes.py @@ -244,7 +244,7 @@ class desc_parameterlist(nodes.Part, nodes.Inline, nodes.FixedTextElement): child_text_separator = ', ' def astext(self): - return '({})'.format(super().astext()) + return f'({super().astext()})' class desc_parameter(nodes.Part, nodes.Inline, nodes.FixedTextElement): diff --git a/sphinx/cmd/quickstart.py b/sphinx/cmd/quickstart.py index 9cfd670a916..183b6e15e82 100644 --- a/sphinx/cmd/quickstart.py +++ b/sphinx/cmd/quickstart.py @@ -364,7 +364,7 @@ def write_file(fpath: str, content: str, newline: Optional[str] = None) -> None: if overwrite or not path.isfile(fpath): if 'quiet' not in d: print(__('Creating file %s.') % fpath) - with open(fpath, 'wt', encoding='utf-8', newline=newline) as f: + with open(fpath, 'w', encoding='utf-8', newline=newline) as f: f.write(content) else: if 'quiet' not in d: diff --git a/sphinx/config.py b/sphinx/config.py index 2906a328578..2e5b009854c 100644 --- a/sphinx/config.py +++ b/sphinx/config.py @@ -464,7 +464,7 @@ def check_confval_types(app: Optional["Sphinx"], config: Config) -> None: if annotations: msg = __("The config value `{name}' has type `{current.__name__}'; " "expected {permitted}.") - wrapped_annotations = ["`{}'".format(c.__name__) for c in annotations] + wrapped_annotations = [f"`{c.__name__}'" for c in annotations] if len(wrapped_annotations) > 2: permitted = "{}, or {}".format( ", ".join(wrapped_annotations[:-1]), diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py index 6e7e9f223ca..7475f044282 100644 --- a/sphinx/domains/c.py +++ b/sphinx/domains/c.py @@ -1826,7 +1826,7 @@ def _add_symbols(self, nestedName: ASTNestedName, Symbol.debug_indent += 1 Symbol.debug_print("nn: ", nestedName) Symbol.debug_print("decl: ", declaration) - Symbol.debug_print("location: {}:{}".format(docname, line)) + Symbol.debug_print(f"location: {docname}:{line}") def onMissingQualifiedSymbol(parentSymbol: "Symbol", ident: ASTIdentifier) -> "Symbol": if Symbol.debug_lookup: @@ -1852,7 +1852,7 @@ def onMissingQualifiedSymbol(parentSymbol: "Symbol", ident: ASTIdentifier) -> "S Symbol.debug_indent += 1 Symbol.debug_print("ident: ", lookupResult.ident) Symbol.debug_print("declaration: ", declaration) - Symbol.debug_print("location: {}:{}".format(docname, line)) + Symbol.debug_print(f"location: {docname}:{line}") Symbol.debug_indent -= 1 symbol = Symbol(parent=lookupResult.parentSymbol, ident=lookupResult.ident, diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py index b509b34893e..7523a1e9ff8 100644 --- a/sphinx/domains/cpp.py +++ b/sphinx/domains/cpp.py @@ -954,7 +954,7 @@ def _stringify(self, transform: StringifyTransform) -> str: def get_id(self, version: int) -> str: # mangle as if it was a function call: ident(literal) - return 'clL_Zli{}E{}E'.format(self.ident.get_id(version), self.literal.get_id(version)) + 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: @@ -4635,7 +4635,7 @@ def _add_symbols(self, nestedName: ASTNestedName, templateDecls: List[Any], Symbol.debug_print("tdecls:", ",".join(str(t) for t in templateDecls)) Symbol.debug_print("nn: ", nestedName) Symbol.debug_print("decl: ", declaration) - Symbol.debug_print("location: {}:{}".format(docname, line)) + Symbol.debug_print(f"location: {docname}:{line}") def onMissingQualifiedSymbol(parentSymbol: "Symbol", identOrOp: Union[ASTIdentifier, ASTOperator], @@ -4673,7 +4673,7 @@ def onMissingQualifiedSymbol(parentSymbol: "Symbol", Symbol.debug_print("identOrOp: ", lookupResult.identOrOp) Symbol.debug_print("templateArgs: ", lookupResult.templateArgs) Symbol.debug_print("declaration: ", declaration) - Symbol.debug_print("location: {}:{}".format(docname, line)) + Symbol.debug_print(f"location: {docname}:{line}") Symbol.debug_indent -= 1 symbol = Symbol(parent=lookupResult.parentSymbol, identOrOp=lookupResult.identOrOp, @@ -6025,23 +6025,23 @@ def _parse_simple_type_specifiers(self) -> ASTTrailingTypeSpecFundamental: 'float', 'double', '__float80', '_Float64x', '__float128', '_Float128'): if typ is not None: - self.fail("Can not have both {} and {}.".format(t, typ)) + self.fail(f"Can not have both {t} and {typ}.") typ = t elif t in ('signed', 'unsigned'): if signedness is not None: - self.fail("Can not have both {} and {}.".format(t, signedness)) + self.fail(f"Can not have both {t} and {signedness}.") signedness = t elif t == 'short': if len(width) != 0: - self.fail("Can not have both {} and {}.".format(t, width[0])) + self.fail(f"Can not have both {t} and {width[0]}.") width.append(t) elif t == 'long': if len(width) != 0 and width[0] != 'long': - self.fail("Can not have both {} and {}.".format(t, width[0])) + self.fail(f"Can not have both {t} and {width[0]}.") width.append(t) elif t in ('_Imaginary', '_Complex'): if modifier is not None: - self.fail("Can not have both {} and {}.".format(t, modifier)) + self.fail(f"Can not have both {t} and {modifier}.") modifier = t self.skip_ws() if len(names) == 0: @@ -6051,41 +6051,41 @@ def _parse_simple_type_specifiers(self) -> ASTTrailingTypeSpecFundamental: 'wchar_t', 'char8_t', 'char16_t', 'char32_t', '__float80', '_Float64x', '__float128', '_Float128'): if modifier is not None: - self.fail("Can not have both {} and {}.".format(typ, modifier)) + self.fail(f"Can not have both {typ} and {modifier}.") if signedness is not None: - self.fail("Can not have both {} and {}.".format(typ, signedness)) + 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))) elif typ == 'char': if modifier is not None: - self.fail("Can not have both {} and {}.".format(typ, modifier)) + 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))) elif typ == 'int': if modifier is not None: - self.fail("Can not have both {} and {}.".format(typ, modifier)) + self.fail(f"Can not have both {typ} and {modifier}.") elif typ in ('__int64', '__int128'): if modifier is not None: - self.fail("Can not have both {} and {}.".format(typ, modifier)) + 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))) elif typ == 'float': if signedness is not None: - self.fail("Can not have both {} and {}.".format(typ, signedness)) + 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))) elif typ == 'double': if signedness is not None: - self.fail("Can not have both {} and {}.".format(typ, signedness)) + 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))) if len(width) == 1 and width[0] != 'long': self.fail("Can not have both {} and {}.".format(typ, ' '.join(width))) elif typ is None: if modifier is not None: - self.fail("Can not have {} without a floating point type.".format(modifier)) + self.fail(f"Can not have {modifier} without a floating point type.") else: - raise AssertionError("Unhandled type {}".format(typ)) + raise AssertionError(f"Unhandled type {typ}") canonNames: List[str] = [] if modifier is not None: diff --git a/sphinx/environment/__init__.py b/sphinx/environment/__init__.py index 6c956ecdddd..05ff4b83feb 100644 --- a/sphinx/environment/__init__.py +++ b/sphinx/environment/__init__.py @@ -76,8 +76,9 @@ if TYPE_CHECKING: from collections.abc import MutableMapping + from typing import Literal - from typing_extensions import Literal, overload + from typing_extensions import overload from sphinx.domains.c import CDomain from sphinx.domains.changeset import ChangeSetDomain diff --git a/sphinx/ext/graphviz.py b/sphinx/ext/graphviz.py index 1ca9dcc729d..df06069c134 100644 --- a/sphinx/ext/graphviz.py +++ b/sphinx/ext/graphviz.py @@ -5,7 +5,7 @@ import re import subprocess from os import path -from subprocess import PIPE, CalledProcessError +from subprocess import CalledProcessError from typing import Any, Dict, List, Optional, Tuple from docutils import nodes @@ -244,7 +244,7 @@ def render_dot(self: SphinxTranslator, code: str, options: Dict, format: str, dot_args.extend(['-Tcmapx', '-o%s.map' % outfn]) try: - ret = subprocess.run(dot_args, input=code.encode(), stdout=PIPE, stderr=PIPE, + ret = subprocess.run(dot_args, input=code.encode(), capture_output=True, cwd=cwd, check=True) if not path.isfile(outfn): raise GraphvizError(__('dot did not produce an output file:\n[stderr]\n%r\n' diff --git a/sphinx/ext/imgconverter.py b/sphinx/ext/imgconverter.py index 599984c1815..e52fbb61e9a 100644 --- a/sphinx/ext/imgconverter.py +++ b/sphinx/ext/imgconverter.py @@ -2,7 +2,7 @@ import subprocess import sys -from subprocess import PIPE, CalledProcessError +from subprocess import CalledProcessError from typing import Any, Dict import sphinx @@ -28,7 +28,7 @@ def is_available(self) -> bool: try: args = [self.config.image_converter, '-version'] logger.debug('Invoking %r ...', args) - subprocess.run(args, stdout=PIPE, stderr=PIPE, check=True) + subprocess.run(args, capture_output=True, check=True) return True except OSError as exc: logger.warning(__( @@ -56,7 +56,7 @@ def convert(self, _from: str, _to: str) -> bool: self.config.image_converter_args + [_from, _to]) logger.debug('Invoking %r ...', args) - subprocess.run(args, stdout=PIPE, stderr=PIPE, check=True) + subprocess.run(args, capture_output=True, check=True) return True except OSError: logger.warning(__('convert command %r cannot be run, ' diff --git a/sphinx/ext/imgmath.py b/sphinx/ext/imgmath.py index f00567e1902..7657ae3aaed 100644 --- a/sphinx/ext/imgmath.py +++ b/sphinx/ext/imgmath.py @@ -6,7 +6,7 @@ import subprocess import tempfile from os import path -from subprocess import PIPE, CalledProcessError +from subprocess import CalledProcessError from typing import Any, Dict, List, Optional, Tuple from docutils import nodes @@ -130,7 +130,7 @@ def compile_math(latex: str, builder: Builder) -> str: command.append('math.tex') try: - subprocess.run(command, stdout=PIPE, stderr=PIPE, cwd=tempdir, check=True, + subprocess.run(command, capture_output=True, cwd=tempdir, check=True, encoding='ascii') return path.join(tempdir, 'math.dvi') except OSError as exc: @@ -145,7 +145,7 @@ def compile_math(latex: str, builder: Builder) -> str: def convert_dvi_to_image(command: List[str], name: str) -> Tuple[str, str]: """Convert DVI file to specific image format.""" try: - ret = subprocess.run(command, stdout=PIPE, stderr=PIPE, check=True, encoding='ascii') + ret = subprocess.run(command, capture_output=True, check=True, encoding='ascii') return ret.stdout, ret.stderr except OSError as exc: logger.warning(__('%s command %r cannot be run (needed for math ' diff --git a/sphinx/ext/intersphinx.py b/sphinx/ext/intersphinx.py index 0d1b25b5b2f..1997045e9e8 100644 --- a/sphinx/ext/intersphinx.py +++ b/sphinx/ext/intersphinx.py @@ -141,9 +141,9 @@ def _get_safe_url(url: str) -> str: else: frags = list(parts) if parts.port: - frags[1] = '{}@{}:{}'.format(parts.username, parts.hostname, parts.port) + frags[1] = f'{parts.username}@{parts.hostname}:{parts.port}' else: - frags[1] = '{}@{}'.format(parts.username, parts.hostname) + frags[1] = f'{parts.username}@{parts.hostname}' return urlunsplit(frags) @@ -334,7 +334,7 @@ def _resolve_reference_in_domain(env: BuildEnvironment, objtypes.append('method') # the inventory contains domain:type as objtype - objtypes = ["{}:{}".format(domain.name, t) for t in objtypes] + objtypes = [f"{domain.name}:{t}" for t in objtypes] # now that the objtypes list is complete we can remove the disabled ones if honor_disabled_refs: diff --git a/sphinx/ext/viewcode.py b/sphinx/ext/viewcode.py index d61837945d6..a890ea5cdc6 100644 --- a/sphinx/ext/viewcode.py +++ b/sphinx/ext/viewcode.py @@ -213,7 +213,7 @@ def should_generate_module_page(app: Sphinx, modname: str) -> bool: if path.getmtime(module_filename) <= path.getmtime(page_filename): # generation is not needed if the HTML page is newer than module file. return False - except IOError: + except OSError: pass return True diff --git a/sphinx/pycode/ast.py b/sphinx/pycode/ast.py index 4997ab09e58..32c01652195 100644 --- a/sphinx/pycode/ast.py +++ b/sphinx/pycode/ast.py @@ -70,7 +70,7 @@ def __init__(self, code: str = '') -> None: def _visit_op(self, node: ast.AST) -> str: return OPERATORS[node.__class__] for _op in OPERATORS: - locals()['visit_{}'.format(_op.__name__)] = _visit_op + locals()[f'visit_{_op.__name__}'] = _visit_op def visit_arg(self, node: ast.arg) -> str: if node.annotation: diff --git a/sphinx/testing/fixtures.py b/sphinx/testing/fixtures.py index d1443834037..88e1bec9bd7 100644 --- a/sphinx/testing/fixtures.py +++ b/sphinx/testing/fixtures.py @@ -4,7 +4,6 @@ import sys from collections import namedtuple from io import StringIO -from subprocess import PIPE from typing import Any, Callable, Dict, Generator, Optional, Tuple import pytest @@ -205,7 +204,7 @@ def if_graphviz_found(app: SphinxTestApp) -> None: graphviz_dot = getattr(app.config, 'graphviz_dot', '') try: if graphviz_dot: - subprocess.run([graphviz_dot, '-V'], stdout=PIPE, stderr=PIPE) # show version + subprocess.run([graphviz_dot, '-V'], capture_output=True) # show version return except OSError: # No such file or directory pass diff --git a/sphinx/util/nodes.py b/sphinx/util/nodes.py index 3549dd190f6..289dcc92e0f 100644 --- a/sphinx/util/nodes.py +++ b/sphinx/util/nodes.py @@ -88,7 +88,7 @@ def get_full_module_name(node: Node) -> str: :param nodes.Node node: target node :return: full module dotted path """ - return '{}.{}'.format(node.__module__, node.__class__.__name__) + return f'{node.__module__}.{node.__class__.__name__}' def repr_domxml(node: Node, length: int = 80) -> str: diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index 846d365d1ed..e3011adf8b5 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -1528,7 +1528,7 @@ def style(string: str) -> str: try: if type == 'single': try: - p1, p2 = [escape(x) for x in split_into(2, 'single', string)] + 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)) except ValueError: @@ -1536,12 +1536,12 @@ def style(string: str) -> str: P = style(p) self.body.append(r'\index{%s@%s%s}' % (p, P, m)) elif type == 'pair': - p1, p2 = [escape(x) for x in split_into(2, 'pair', string)] + p1, p2 = (escape(x) for x in split_into(2, 'pair', string)) P1, P2 = style(p1), style(p2) self.body.append(r'\index{%s@%s!%s@%s%s}\index{%s@%s!%s@%s%s}' % (p1, P1, p2, P2, m, p2, P2, p1, P1, m)) elif type == 'triple': - p1, p2, p3 = [escape(x) for x in split_into(3, 'triple', string)] + p1, p2, p3 = (escape(x) for x in split_into(3, 'triple', string)) P1, P2, P3 = style(p1), style(p2), style(p3) self.body.append( r'\index{%s@%s!%s %s@%s %s%s}' @@ -1551,11 +1551,11 @@ def style(string: str) -> str: p2, P2, p3, p1, P3, P1, m, p3, P3, p1, p2, P1, P2, m)) elif type == 'see': - p1, p2 = [escape(x) for x in split_into(2, 'see', string)] + 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)) elif type == 'seealso': - p1, p2 = [escape(x) for x in split_into(2, 'seealso', string)] + 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)) else: diff --git a/tests/roots/test-apidoc-toc/mypackage/main.py b/tests/roots/test-apidoc-toc/mypackage/main.py index d448cc84733..f532813a722 100755 --- a/tests/roots/test-apidoc-toc/mypackage/main.py +++ b/tests/roots/test-apidoc-toc/mypackage/main.py @@ -6,10 +6,10 @@ import mod_something if __name__ == "__main__": - print("Hello, world! -> something returns: {}".format(mod_something.something())) + print(f"Hello, world! -> something returns: {mod_something.something()}") res_path = \ os.path.join(os.path.dirname(mod_resource.__file__), 'resource.txt') with open(res_path, encoding='utf-8') as f: text = f.read() - print("From mod_resource:resource.txt -> {}".format(text)) + print(f"From mod_resource:resource.txt -> {text}") diff --git a/tests/roots/test-autosummary/underscore_module_.py b/tests/roots/test-autosummary/underscore_module_.py index c18697cd259..8584e60787b 100644 --- a/tests/roots/test-autosummary/underscore_module_.py +++ b/tests/roots/test-autosummary/underscore_module_.py @@ -3,7 +3,7 @@ """ -class class_(object): +class class_: """ Class """ def method_(_arg): """ Method """ diff --git a/tests/roots/test-changes/conf.py b/tests/roots/test-changes/conf.py index 2fedcb1999a..e9158c42988 100644 --- a/tests/roots/test-changes/conf.py +++ b/tests/roots/test-changes/conf.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - project = 'Sphinx ChangesBuilder tests' copyright = '2007-2022 by the Sphinx team, see AUTHORS' version = '0.6' diff --git a/tests/roots/test-correct-year/conf.py b/tests/roots/test-correct-year/conf.py index 6aac1743e71..814c08b55e0 100644 --- a/tests/roots/test-correct-year/conf.py +++ b/tests/roots/test-correct-year/conf.py @@ -1,2 +1 @@ - copyright = '2006-2009, Author' diff --git a/tests/roots/test-directive-only/conf.py b/tests/roots/test-directive-only/conf.py index b9209f08b2e..191d0f5982a 100644 --- a/tests/roots/test-directive-only/conf.py +++ b/tests/roots/test-directive-only/conf.py @@ -1,3 +1,2 @@ - project = 'test-directive-only' exclude_patterns = ['_build'] diff --git a/tests/roots/test-ext-autodoc/autodoc_dummy_bar.py b/tests/roots/test-ext-autodoc/autodoc_dummy_bar.py index 151818b36dd..3b5bbfdd1cb 100644 --- a/tests/roots/test-ext-autodoc/autodoc_dummy_bar.py +++ b/tests/roots/test-ext-autodoc/autodoc_dummy_bar.py @@ -1,6 +1,6 @@ from bug2437.autodoc_dummy_foo import Foo -class Bar(object): +class Bar: """Dummy class Bar with alias.""" my_name = Foo diff --git a/tests/roots/test-ext-autodoc/bug2437/autodoc_dummy_foo.py b/tests/roots/test-ext-autodoc/bug2437/autodoc_dummy_foo.py index b578a225507..9c954d80a52 100644 --- a/tests/roots/test-ext-autodoc/bug2437/autodoc_dummy_foo.py +++ b/tests/roots/test-ext-autodoc/bug2437/autodoc_dummy_foo.py @@ -1,3 +1,3 @@ -class Foo(object): +class Foo: """Dummy class Foo.""" pass diff --git a/tests/roots/test-ext-autodoc/target/__init__.py b/tests/roots/test-ext-autodoc/target/__init__.py index 0d39c667258..bb2290be6e8 100644 --- a/tests/roots/test-ext-autodoc/target/__init__.py +++ b/tests/roots/test-ext-autodoc/target/__init__.py @@ -33,7 +33,7 @@ def template(cls, a, b, c, d=4, e=5, f=6): return classmethod(function) -class Class(object): +class Class: """Class to document.""" def meth(self): @@ -96,10 +96,10 @@ def function(foo, *args, **kwds): pass -class Outer(object): +class Outer: """Foo""" - class Inner(object): + class Inner: """Foo""" def meth(self): @@ -113,7 +113,7 @@ class InnerChild(Outer.Inner): """InnerChild docstring""" -class DocstringSig(object): +class DocstringSig: def __new__(cls, *new_args, **new_kwargs): """__new__(cls, d, e=1) -> DocstringSig First line of docstring @@ -164,12 +164,12 @@ def __repr__(self): return self -class AttCls(object): +class AttCls: a1 = StrRepr('hello\nworld') a2 = None -class InstAttCls(object): +class InstAttCls: """Class with documented class and instance attributes.""" #: Doc comment for class attribute InstAttCls.ca1. @@ -189,7 +189,7 @@ def __init__(self): """Docstring for instance attribute InstAttCls.ia2.""" -class CustomIter(object): +class CustomIter: def __init__(self): """Create a new `CustomIter`.""" self.values = range(10) diff --git a/tests/roots/test-ext-autodoc/target/descriptor.py b/tests/roots/test-ext-autodoc/target/descriptor.py index 63d179b65a3..2857c99f9d4 100644 --- a/tests/roots/test-ext-autodoc/target/descriptor.py +++ b/tests/roots/test-ext-autodoc/target/descriptor.py @@ -1,4 +1,4 @@ -class CustomDataDescriptor(object): +class CustomDataDescriptor: """Descriptor class docstring.""" def __init__(self, doc): diff --git a/tests/roots/test-ext-autodoc/target/inheritance.py b/tests/roots/test-ext-autodoc/target/inheritance.py index 85d95cd742e..e06f7a842b2 100644 --- a/tests/roots/test-ext-autodoc/target/inheritance.py +++ b/tests/roots/test-ext-autodoc/target/inheritance.py @@ -1,4 +1,4 @@ -class Base(object): +class Base: #: docstring inheritedattr = None diff --git a/tests/roots/test-ext-autodoc/target/need_mocks.py b/tests/roots/test-ext-autodoc/target/need_mocks.py index 45b3ade06de..881220bd09e 100644 --- a/tests/roots/test-ext-autodoc/target/need_mocks.py +++ b/tests/roots/test-ext-autodoc/target/need_mocks.py @@ -1,4 +1,3 @@ - import missing_module import missing_package1.missing_module1 from missing_module import missing_name @@ -20,7 +19,7 @@ def func(arg: missing_module.Class): pass -class TestAutodoc(object): +class TestAutodoc: """TestAutodoc docstring.""" #: docstring diff --git a/tests/roots/test-ext-autodoc/target/partialmethod.py b/tests/roots/test-ext-autodoc/target/partialmethod.py index 82843461faa..20d75e91d21 100644 --- a/tests/roots/test-ext-autodoc/target/partialmethod.py +++ b/tests/roots/test-ext-autodoc/target/partialmethod.py @@ -1,7 +1,7 @@ from functools import partialmethod -class Cell(object): +class Cell: """An example for partialmethod. refs: https://docs.python.jp/3/library/functools.html#functools.partialmethod diff --git a/tests/roots/test-ext-autodoc/target/typed_vars.py b/tests/roots/test-ext-autodoc/target/typed_vars.py index f909b80f16b..0fe7468c84f 100644 --- a/tests/roots/test-ext-autodoc/target/typed_vars.py +++ b/tests/roots/test-ext-autodoc/target/typed_vars.py @@ -8,7 +8,7 @@ class _Descriptor: def __init__(self, name): - self.__doc__ = "This is {}".format(name) + self.__doc__ = f"This is {name}" def __get__(self): pass diff --git a/tests/roots/test-ext-inheritance_diagram/example/sphinx.py b/tests/roots/test-ext-inheritance_diagram/example/sphinx.py index 5eb8a2291da..2bfbf4c5990 100644 --- a/tests/roots/test-ext-inheritance_diagram/example/sphinx.py +++ b/tests/roots/test-ext-inheritance_diagram/example/sphinx.py @@ -1,5 +1,5 @@ # example.sphinx -class DummyClass(object): +class DummyClass: pass diff --git a/tests/roots/test-ext-inheritance_diagram/test.py b/tests/roots/test-ext-inheritance_diagram/test.py index 7d5cabeefe2..4f73c4707d5 100644 --- a/tests/roots/test-ext-inheritance_diagram/test.py +++ b/tests/roots/test-ext-inheritance_diagram/test.py @@ -1,4 +1,4 @@ -class Foo(object): +class Foo: pass diff --git a/tests/roots/test-ext-viewcode-find/not_a_package/submodule.py b/tests/roots/test-ext-viewcode-find/not_a_package/submodule.py index 7bb36943be1..ba8be78de5f 100644 --- a/tests/roots/test-ext-viewcode-find/not_a_package/submodule.py +++ b/tests/roots/test-ext-viewcode-find/not_a_package/submodule.py @@ -17,13 +17,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-inheritance/dummy/test.py b/tests/roots/test-inheritance/dummy/test.py index 51bd9a7a404..12fe8d900f3 100644 --- a/tests/roots/test-inheritance/dummy/test.py +++ b/tests/roots/test-inheritance/dummy/test.py @@ -11,7 +11,7 @@ """ -class A(object): +class A: pass diff --git a/tests/roots/test-inheritance/dummy/test_nested.py b/tests/roots/test-inheritance/dummy/test_nested.py index 89289fe44fc..4b6801892ec 100644 --- a/tests/roots/test-inheritance/dummy/test_nested.py +++ b/tests/roots/test-inheritance/dummy/test_nested.py @@ -2,8 +2,8 @@ """ -class A(object): - class B(object): +class A: + class B: pass diff --git a/tests/roots/test-root/autodoc_target.py b/tests/roots/test-root/autodoc_target.py index a49ffc1fffd..59f6c74d64c 100644 --- a/tests/roots/test-root/autodoc_target.py +++ b/tests/roots/test-root/autodoc_target.py @@ -19,7 +19,7 @@ def f(self): """Exception method.""" -class CustomDataDescriptor(object): +class CustomDataDescriptor: """Descriptor class docstring.""" def __init__(self, doc): @@ -56,7 +56,7 @@ def template(cls, a, b, c, d=4, e=5, f=6): return classmethod(function) -class Base(object): +class Base: def inheritedmeth(self): """Inherited function.""" @@ -136,10 +136,10 @@ def function(foo, *args, **kwds): pass -class Outer(object): +class Outer: """Foo""" - class Inner(object): + class Inner: """Foo""" def meth(self): @@ -149,7 +149,7 @@ def meth(self): factory = dict -class DocstringSig(object): +class DocstringSig: def meth(self): """meth(FOO, BAR=1) -> BAZ First line of docstring @@ -184,12 +184,12 @@ def __repr__(self): return self -class AttCls(object): +class AttCls: a1 = StrRepr('hello\nworld') a2 = None -class InstAttCls(object): +class InstAttCls: """Class with documented class and instance attributes.""" #: Doc comment for class attribute InstAttCls.ca1. diff --git a/tests/roots/test-warnings/autodoc_fodder.py b/tests/roots/test-warnings/autodoc_fodder.py index e5fd74139f8..59e4e210f3a 100644 --- a/tests/roots/test-warnings/autodoc_fodder.py +++ b/tests/roots/test-warnings/autodoc_fodder.py @@ -1,5 +1,4 @@ - -class MarkupError(object): +class MarkupError: """ .. note:: This is a docstring with a small markup error which should have diff --git a/tests/test_build_epub.py b/tests/test_build_epub.py index 80525112b1e..becde92cd78 100644 --- a/tests/test_build_epub.py +++ b/tests/test_build_epub.py @@ -2,7 +2,7 @@ import os import subprocess -from subprocess import PIPE, CalledProcessError +from subprocess import CalledProcessError from xml.etree import ElementTree import pytest @@ -11,7 +11,7 @@ # check given command is runnable def runnable(command): try: - subprocess.run(command, stdout=PIPE, stderr=PIPE, check=True) + subprocess.run(command, capture_output=True, check=True) return True except (OSError, CalledProcessError): return False # command not found or exit with non-zero @@ -377,7 +377,7 @@ def test_run_epubcheck(app): if runnable(['java', '-version']) and os.path.exists(epubcheck): try: subprocess.run(['java', '-jar', epubcheck, app.outdir / 'SphinxTests.epub'], - stdout=PIPE, stderr=PIPE, check=True) + capture_output=True, check=True) except CalledProcessError as exc: print(exc.stdout.decode('utf-8')) print(exc.stderr.decode('utf-8')) diff --git a/tests/test_build_gettext.py b/tests/test_build_gettext.py index 20fe60e8502..630f0760c70 100644 --- a/tests/test_build_gettext.py +++ b/tests/test_build_gettext.py @@ -4,7 +4,7 @@ import os import re import subprocess -from subprocess import PIPE, CalledProcessError +from subprocess import CalledProcessError import pytest @@ -54,7 +54,7 @@ def test_msgfmt(app): with cd(app.outdir): try: args = ['msginit', '--no-translator', '-i', 'markup.pot', '--locale', 'en_US'] - subprocess.run(args, stdout=PIPE, stderr=PIPE, check=True) + subprocess.run(args, capture_output=True, check=True) except OSError: pytest.skip() # most likely msginit was not found except CalledProcessError as exc: @@ -66,7 +66,7 @@ def test_msgfmt(app): try: args = ['msgfmt', 'en_US.po', '-o', os.path.join('en', 'LC_MESSAGES', 'test_root.mo')] - subprocess.run(args, stdout=PIPE, stderr=PIPE, check=True) + subprocess.run(args, capture_output=True, check=True) except OSError: pytest.skip() # most likely msgfmt was not found except CalledProcessError as exc: diff --git a/tests/test_build_html.py b/tests/test_build_html.py index fa0bbac7c3d..dee65613f9d 100644 --- a/tests/test_build_html.py +++ b/tests/test_build_html.py @@ -105,9 +105,9 @@ def get_text(node): if all(not rex.search(get_text(node)) for node in nodes): return - raise AssertionError(('%r not found in any node matching ' - 'path %s in %s: %r' % (check, path, fname, - [node.text for node in nodes]))) + raise AssertionError('%r not found in any node matching ' + 'path %s in %s: %r' % (check, path, fname, + [node.text for node in nodes])) @pytest.mark.sphinx('html', testroot='warnings') diff --git a/tests/test_build_latex.py b/tests/test_build_latex.py index f8b06562b51..bfb12695337 100644 --- a/tests/test_build_latex.py +++ b/tests/test_build_latex.py @@ -5,7 +5,7 @@ import subprocess from itertools import product from shutil import copyfile -from subprocess import PIPE, CalledProcessError +from subprocess import CalledProcessError import pytest @@ -36,7 +36,7 @@ # only run latex if all needed packages are there def kpsetest(*filenames): try: - subprocess.run(['kpsewhich'] + list(filenames), stdout=PIPE, stderr=PIPE, check=True) + subprocess.run(['kpsewhich'] + list(filenames), capture_output=True, check=True) return True except (OSError, CalledProcessError): return False # command not found or exit with non-zero @@ -55,7 +55,7 @@ def compile_latex_document(app, filename='python.tex'): '--interaction=nonstopmode', '-output-directory=%s' % app.config.latex_engine, filename] - subprocess.run(args, stdout=PIPE, stderr=PIPE, check=True) + subprocess.run(args, capture_output=True, check=True) except OSError as exc: # most likely the latex executable was not found raise pytest.skip.Exception from exc except CalledProcessError as exc: diff --git a/tests/test_build_texinfo.py b/tests/test_build_texinfo.py index b33a7e01fc3..974cb1965f5 100644 --- a/tests/test_build_texinfo.py +++ b/tests/test_build_texinfo.py @@ -3,7 +3,7 @@ import os import re import subprocess -from subprocess import PIPE, CalledProcessError +from subprocess import CalledProcessError from unittest.mock import Mock import pytest @@ -49,7 +49,7 @@ def test_texinfo(app, status, warning): # now, try to run makeinfo over it try: args = ['makeinfo', '--no-split', 'sphinxtests.texi'] - subprocess.run(args, stdout=PIPE, stderr=PIPE, cwd=app.outdir, check=True) + subprocess.run(args, capture_output=True, cwd=app.outdir, check=True) except OSError as exc: raise pytest.skip.Exception from exc # most likely makeinfo was not found except CalledProcessError as exc: diff --git a/tests/test_domain_c.py b/tests/test_domain_c.py index 8a9a045680d..9718297ab48 100644 --- a/tests/test_domain_c.py +++ b/tests/test_domain_c.py @@ -470,12 +470,12 @@ def test_domain_c_ast_function_definitions(): cvrs = ['', 'const', 'volatile', 'restrict', 'restrict volatile const'] for cvr in cvrs: space = ' ' if len(cvr) != 0 else '' - check('function', 'void f(int arr[{}*])'.format(cvr), {1: 'f'}) - check('function', 'void f(int arr[{}])'.format(cvr), {1: 'f'}) - check('function', 'void f(int arr[{}{}42])'.format(cvr, space), {1: 'f'}) - check('function', 'void f(int arr[static{}{} 42])'.format(space, cvr), {1: 'f'}) - check('function', 'void f(int arr[{}{}static 42])'.format(cvr, space), {1: 'f'}, - output='void f(int arr[static{}{} 42])'.format(space, cvr)) + check('function', f'void f(int arr[{cvr}*])', {1: 'f'}) + check('function', f'void f(int arr[{cvr}])', {1: 'f'}) + check('function', f'void f(int arr[{cvr}{space}42])', {1: 'f'}) + check('function', f'void f(int arr[static{space}{cvr} 42])', {1: 'f'}) + check('function', f'void f(int arr[{cvr}{space}static 42])', {1: 'f'}, + output=f'void f(int arr[static{space}{cvr} 42])') check('function', 'void f(int arr[const static volatile 42])', {1: 'f'}, output='void f(int arr[static volatile const 42])') @@ -611,9 +611,9 @@ def split_warnigns(warning): def filter_warnings(warning, file): lines = split_warnigns(warning) - res = [l for l in lines if "domain-c" in l and "{}.rst".format(file) in l and + res = [l for l in lines if "domain-c" in l and f"{file}.rst" in l and "WARNING: document isn't included in any toctree" not in l] - print("Filtered warnings for file '{}':".format(file)) + print(f"Filtered warnings for file '{file}':") for w in res: print(w) return res @@ -652,7 +652,7 @@ def test_domain_c_build_namespace(app, status, warning): assert len(ws) == 0 t = (app.outdir / "namespace.html").read_text(encoding='utf8') for id_ in ('NS.NSVar', 'NULLVar', 'ZeroVar', 'NS2.NS3.NS2NS3Var', 'PopVar'): - assert 'id="c.{}"'.format(id_) in t + assert f'id="c.{id_}"' in t @pytest.mark.sphinx(testroot='domain-c', confoverrides={'nitpicky': True}) diff --git a/tests/test_domain_cpp.py b/tests/test_domain_cpp.py index 5e9bc6aa301..93a43c754e1 100644 --- a/tests/test_domain_cpp.py +++ b/tests/test_domain_cpp.py @@ -218,7 +218,7 @@ class Config: ('\\U0001f34c', '127820'), ('\\U0001F34C', '127820')] for p, t in charPrefixAndIds: for c, val in chars: - exprCheck("{}'{}'".format(p, c), t + val) + exprCheck(f"{p}'{c}'", t + val) # user-defined literals for i in ints: exprCheck(i + '_udl', 'clL_Zli4_udlEL' + i.replace("'", "") + 'EE') @@ -230,7 +230,7 @@ class Config: exprCheck('0x' + f + '_udl', 'clL_Zli4_udlEL0x' + f.replace("'", "") + 'EE') for p, t in charPrefixAndIds: for c, val in chars: - exprCheck("{}'{}'_udl".format(p, c), 'clL_Zli4_udlE' + t + val + 'E') + exprCheck(f"{p}'{c}'_udl", 'clL_Zli4_udlE' + t + val + 'E') exprCheck('"abc"_udl', 'clL_Zli4_udlELA3_KcEE') # from issue #7294 exprCheck('6.62607015e-34q_J', 'clL_Zli3q_JEL6.62607015e-34EE') @@ -1084,9 +1084,9 @@ def parse_template_parameter(param: str): def filter_warnings(warning, file): lines = warning.getvalue().split("\n") - res = [l for l in lines if "domain-cpp" in l and "{}.rst".format(file) in l and + res = [l for l in lines if "domain-cpp" in l and f"{file}.rst" in l and "WARNING: document isn't included in any toctree" not in l] - print("Filtered warnings for file '{}':".format(file)) + print(f"Filtered warnings for file '{file}':") for w in res: print(w) return res @@ -1169,10 +1169,10 @@ def test_domain_cpp_build_misuse_of_roles(app, status, warning): txtTargetType = "function" if targetType == "func" else targetType for r in allRoles: if r not in roles: - warn.append("WARNING: cpp:{} targets a {} (".format(r, txtTargetType)) + warn.append(f"WARNING: cpp:{r} targets a {txtTargetType} (") if targetType == 'templateParam': - warn.append("WARNING: cpp:{} targets a {} (".format(r, txtTargetType)) - warn.append("WARNING: cpp:{} targets a {} (".format(r, txtTargetType)) + warn.append(f"WARNING: cpp:{r} targets a {txtTargetType} (") + warn.append(f"WARNING: cpp:{r} targets a {txtTargetType} (") warn = sorted(warn) for w in ws: assert "targets a" in w @@ -1326,7 +1326,7 @@ def __init__(self, role, root, contents): for role in (expr_role, texpr_role): name = role.name - expect = '`{name}` puts the domain and role classes at its root'.format(name=name) + expect = f'`{name}` puts the domain and role classes at its root' assert {'sig', 'sig-inline', 'cpp', name} <= role.classes, expect # reference classes diff --git a/tests/test_ext_apidoc.py b/tests/test_ext_apidoc.py index 2d427417b3e..66b106fe6aa 100644 --- a/tests/test_ext_apidoc.py +++ b/tests/test_ext_apidoc.py @@ -318,7 +318,7 @@ def test_toc_all_references_should_exist_pep420_enabled(make_app, apidoc): if ref and ref[0] in (':', '#'): continue found_refs.append(ref) - filename = "{}.rst".format(ref) + filename = f"{ref}.rst" if not (outdir / filename).isfile(): missing_files.append(filename) @@ -347,7 +347,7 @@ def test_toc_all_references_should_exist_pep420_disabled(make_app, apidoc): for ref in refs: if ref and ref[0] in (':', '#'): continue - filename = "{}.rst".format(ref) + filename = f"{ref}.rst" found_refs.append(ref) if not (outdir / filename).isfile(): missing_files.append(filename) diff --git a/tests/test_ext_doctest.py b/tests/test_ext_doctest.py index 6c628904f27..e03c12540ac 100644 --- a/tests/test_ext_doctest.py +++ b/tests/test_ext_doctest.py @@ -117,7 +117,7 @@ def test_skipif(app, status, warning): def record(directive, part, should_skip): global recorded_calls recorded_calls[(directive, part, should_skip)] += 1 - return 'Recorded {} {} {}'.format(directive, part, should_skip) + return f'Recorded {directive} {part} {should_skip}' @pytest.mark.sphinx('doctest', testroot='ext-doctest-with-autodoc') diff --git a/tests/test_ext_imgconverter.py b/tests/test_ext_imgconverter.py index 8b938a0dc2b..5132390cf75 100644 --- a/tests/test_ext_imgconverter.py +++ b/tests/test_ext_imgconverter.py @@ -1,7 +1,6 @@ """Test sphinx.ext.imgconverter extension.""" import subprocess -from subprocess import PIPE import pytest @@ -11,7 +10,7 @@ def if_converter_found(app): image_converter = getattr(app.config, 'image_converter', '') try: if image_converter: - subprocess.run([image_converter, '-version'], stdout=PIPE, stderr=PIPE) # show version + subprocess.run([image_converter, '-version'], capture_output=True) # show version return except OSError: # No such file or directory pass diff --git a/tests/test_util_inspect.py b/tests/test_util_inspect.py index bb43fb30d85..753b363da0d 100644 --- a/tests/test_util_inspect.py +++ b/tests/test_util_inspect.py @@ -716,7 +716,7 @@ def meth(self): """ class Bar(Foo): - @functools.lru_cache() # noqa: B019 + @functools.lru_cache # noqa: B019 def meth(self): # inherited and decorated method pass diff --git a/utils/bump_version.py b/utils/bump_version.py index e2aefa842e4..a76391d1c30 100755 --- a/utils/bump_version.py +++ b/utils/bump_version.py @@ -24,7 +24,7 @@ def stringify_version(version_info, in_develop=True): def bump_version(path, version_info, in_develop=True): version = stringify_version(version_info, in_develop) - with open(path, 'r', encoding='utf-8') as f: + with open(path, encoding='utf-8') as f: lines = f.read().splitlines() for i, line in enumerate(lines):