From c0532dda18a5cfd0e6f67113bb164485fa80eb86 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 13 Mar 2024 15:30:18 +0200 Subject: [PATCH] [pre-commit.ci] pre-commit autoupdate (#12115) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Pierre Sassoulas Co-authored-by: Ran Benita --- .pre-commit-config.yaml | 4 +- pyproject.toml | 2 + scripts/generate-gh-release-notes.py | 1 + scripts/prepare-release-pr.py | 1 + scripts/release.py | 1 + src/_pytest/__init__.py | 2 +- src/_pytest/_code/code.py | 28 +++++++------- src/_pytest/_code/source.py | 6 +-- src/_pytest/_io/terminalwriter.py | 3 ++ src/_pytest/_py/path.py | 37 ++++++------------- src/_pytest/assertion/__init__.py | 1 + src/_pytest/assertion/rewrite.py | 14 +++---- src/_pytest/assertion/util.py | 6 +-- src/_pytest/cacheprovider.py | 3 +- src/_pytest/capture.py | 33 +++++++---------- src/_pytest/compat.py | 2 +- src/_pytest/config/__init__.py | 1 + src/_pytest/config/argparsing.py | 3 +- src/_pytest/debugging.py | 5 +-- src/_pytest/doctest.py | 1 + src/_pytest/fixtures.py | 34 ++++++++--------- src/_pytest/freeze_support.py | 2 +- src/_pytest/helpconfig.py | 1 + src/_pytest/hookspec.py | 1 + src/_pytest/junitxml.py | 5 ++- src/_pytest/logging.py | 5 ++- src/_pytest/main.py | 6 +-- src/_pytest/mark/structures.py | 24 +++++------- src/_pytest/monkeypatch.py | 7 ++-- src/_pytest/nodes.py | 6 +-- src/_pytest/pastebin.py | 1 + src/_pytest/pytester.py | 22 ++++------- src/_pytest/python.py | 1 + src/_pytest/python_api.py | 16 ++++---- src/_pytest/recwarn.py | 16 +++----- src/_pytest/reports.py | 9 ++--- src/_pytest/runner.py | 6 +-- src/_pytest/setuponly.py | 4 +- src/_pytest/skipping.py | 3 +- src/_pytest/terminal.py | 1 + src/_pytest/tmpdir.py | 1 + src/_pytest/unittest.py | 13 +++---- src/pytest/__init__.py | 1 + testing/_py/test_local.py | 10 ++--- testing/code/test_excinfo.py | 2 +- .../acceptance/fixture_mock_integration.py | 1 + .../unittest/test_setup_skip.py | 1 + .../unittest/test_setup_skip_class.py | 1 + .../unittest/test_setup_skip_module.py | 1 + .../unittest/test_unittest_asynctest.py | 1 + testing/io/test_wcwidth.py | 4 +- testing/python/metafunc.py | 4 +- testing/test_config.py | 2 +- testing/test_debugging.py | 2 +- testing/test_junitxml.py | 2 +- testing/test_mark.py | 4 +- testing/test_pathlib.py | 14 +++---- testing/test_reports.py | 6 +-- testing/test_runner_xunit.py | 1 + testing/test_terminal.py | 1 + testing/typing_checks.py | 1 + 61 files changed, 185 insertions(+), 212 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 78cf36bae..deb187fec 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.2.2" + rev: "v0.3.2" hooks: - id: ruff args: ["--fix"] @@ -26,7 +26,7 @@ repos: hooks: - id: python-use-type-annotations - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.8.0 + rev: v1.9.0 hooks: - id: mypy files: ^(src/|testing/|scripts/) diff --git a/pyproject.toml b/pyproject.toml index e14556f2f..7d1b8a22d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -281,6 +281,7 @@ template = "changelog/_template.rst" showcontent = true [tool.mypy] +files = ["src", "testing", "scripts"] mypy_path = ["src"] check_untyped_defs = true disallow_any_generics = true @@ -293,3 +294,4 @@ warn_return_any = true warn_unreachable = true warn_unused_configs = true no_implicit_reexport = true +warn_unused_ignores = true diff --git a/scripts/generate-gh-release-notes.py b/scripts/generate-gh-release-notes.py index c27f5774b..4222702d5 100644 --- a/scripts/generate-gh-release-notes.py +++ b/scripts/generate-gh-release-notes.py @@ -8,6 +8,7 @@ our CHANGELOG) into Markdown (which is required by GitHub Releases). Requires Python3.6+. """ + from pathlib import Path import re import sys diff --git a/scripts/prepare-release-pr.py b/scripts/prepare-release-pr.py index 8a9f0aa0f..7dabbd3b3 100644 --- a/scripts/prepare-release-pr.py +++ b/scripts/prepare-release-pr.py @@ -13,6 +13,7 @@ After that, it will create a release using the `release` tox environment, and pu **Token**: currently the token from the GitHub Actions is used, pushed with `pytest bot ` commit author. """ + import argparse from pathlib import Path import re diff --git a/scripts/release.py b/scripts/release.py index 73f5f52b1..bcbc4262d 100644 --- a/scripts/release.py +++ b/scripts/release.py @@ -1,5 +1,6 @@ # mypy: disallow-untyped-defs """Invoke development tasks.""" + import argparse import os from pathlib import Path diff --git a/src/_pytest/__init__.py b/src/_pytest/__init__.py index 9062768ea..b694a5f24 100644 --- a/src/_pytest/__init__.py +++ b/src/_pytest/__init__.py @@ -7,4 +7,4 @@ except ImportError: # pragma: no cover # broken installation, we don't even try # unknown only works because we do poor mans version compare __version__ = "unknown" - version_tuple = (0, 0, "unknown") # type:ignore[assignment] + version_tuple = (0, 0, "unknown") diff --git a/src/_pytest/_code/code.py b/src/_pytest/_code/code.py index 12168be60..64a8f243a 100644 --- a/src/_pytest/_code/code.py +++ b/src/_pytest/_code/code.py @@ -279,9 +279,9 @@ class TracebackEntry: Mostly for internal use. """ - tbh: Union[ - bool, Callable[[Optional[ExceptionInfo[BaseException]]], bool] - ] = False + tbh: Union[bool, Callable[[Optional[ExceptionInfo[BaseException]]], bool]] = ( + False + ) for maybe_ns_dct in (self.frame.f_locals, self.frame.f_globals): # in normal cases, f_locals and f_globals are dictionaries # however via `exec(...)` / `eval(...)` they can be other types @@ -378,12 +378,10 @@ class Traceback(List[TracebackEntry]): return self @overload - def __getitem__(self, key: "SupportsIndex") -> TracebackEntry: - ... + def __getitem__(self, key: "SupportsIndex") -> TracebackEntry: ... @overload - def __getitem__(self, key: slice) -> "Traceback": - ... + def __getitem__(self, key: slice) -> "Traceback": ... def __getitem__( self, key: Union["SupportsIndex", slice] @@ -1051,13 +1049,13 @@ class FormattedExcinfo: # full support for exception groups added to ExceptionInfo. # See https://github.com/pytest-dev/pytest/issues/9159 if isinstance(e, BaseExceptionGroup): - reprtraceback: Union[ - ReprTracebackNative, ReprTraceback - ] = ReprTracebackNative( - traceback.format_exception( - type(excinfo_.value), - excinfo_.value, - excinfo_.traceback[0]._rawentry, + reprtraceback: Union[ReprTracebackNative, ReprTraceback] = ( + ReprTracebackNative( + traceback.format_exception( + type(excinfo_.value), + excinfo_.value, + excinfo_.traceback[0]._rawentry, + ) ) ) else: @@ -1348,7 +1346,7 @@ def getfslineno(obj: object) -> Tuple[Union[str, Path], int]: # in 6ec13a2b9. It ("place_as") appears to be something very custom. obj = get_real_func(obj) if hasattr(obj, "place_as"): - obj = obj.place_as # type: ignore[attr-defined] + obj = obj.place_as try: code = Code.from_function(obj) diff --git a/src/_pytest/_code/source.py b/src/_pytest/_code/source.py index dac3c3867..7fa577e03 100644 --- a/src/_pytest/_code/source.py +++ b/src/_pytest/_code/source.py @@ -47,12 +47,10 @@ class Source: __hash__ = None # type: ignore @overload - def __getitem__(self, key: int) -> str: - ... + def __getitem__(self, key: int) -> str: ... @overload - def __getitem__(self, key: slice) -> "Source": - ... + def __getitem__(self, key: slice) -> "Source": ... def __getitem__(self, key: Union[int, slice]) -> Union[str, "Source"]: if isinstance(key, int): diff --git a/src/_pytest/_io/terminalwriter.py b/src/_pytest/_io/terminalwriter.py index badbb7e4a..deb6ecc3c 100644 --- a/src/_pytest/_io/terminalwriter.py +++ b/src/_pytest/_io/terminalwriter.py @@ -9,6 +9,7 @@ from typing import Optional from typing import Sequence from typing import TextIO +from ..compat import assert_never from .wcwidth import wcswidth @@ -209,6 +210,8 @@ class TerminalWriter: from pygments.lexers.python import PythonLexer as Lexer elif lexer == "diff": from pygments.lexers.diff import DiffLexer as Lexer + else: + assert_never(lexer) from pygments import highlight import pygments.util except ImportError: diff --git a/src/_pytest/_py/path.py b/src/_pytest/_py/path.py index 7701561d9..7bb3693f9 100644 --- a/src/_pytest/_py/path.py +++ b/src/_pytest/_py/path.py @@ -1,5 +1,6 @@ # mypy: allow-untyped-defs """local path implementation.""" + from __future__ import annotations import atexit @@ -205,12 +206,10 @@ class Stat: if TYPE_CHECKING: @property - def size(self) -> int: - ... + def size(self) -> int: ... @property - def mtime(self) -> float: - ... + def mtime(self) -> float: ... def __getattr__(self, name: str) -> Any: return getattr(self._osstatresult, "st_" + name) @@ -225,7 +224,7 @@ class Stat: raise NotImplementedError("XXX win32") import pwd - entry = error.checked_call(pwd.getpwuid, self.uid) # type:ignore[attr-defined] + entry = error.checked_call(pwd.getpwuid, self.uid) # type:ignore[attr-defined,unused-ignore] return entry[0] @property @@ -235,7 +234,7 @@ class Stat: raise NotImplementedError("XXX win32") import grp - entry = error.checked_call(grp.getgrgid, self.gid) # type:ignore[attr-defined] + entry = error.checked_call(grp.getgrgid, self.gid) # type:ignore[attr-defined,unused-ignore] return entry[0] def isdir(self): @@ -253,7 +252,7 @@ def getuserid(user): import pwd if not isinstance(user, int): - user = pwd.getpwnam(user)[2] # type:ignore[attr-defined] + user = pwd.getpwnam(user)[2] # type:ignore[attr-defined,unused-ignore] return user @@ -261,7 +260,7 @@ def getgroupid(group): import grp if not isinstance(group, int): - group = grp.getgrnam(group)[2] # type:ignore[attr-defined] + group = grp.getgrnam(group)[2] # type:ignore[attr-defined,unused-ignore] return group @@ -318,7 +317,7 @@ class LocalPath: def readlink(self) -> str: """Return value of a symbolic link.""" # https://github.com/python/mypy/issues/12278 - return error.checked_call(os.readlink, self.strpath) # type: ignore[arg-type,return-value] + return error.checked_call(os.readlink, self.strpath) # type: ignore[arg-type,return-value,unused-ignore] def mklinkto(self, oldname): """Posix style hard link to another name.""" @@ -757,15 +756,11 @@ class LocalPath: if ensure: self.dirpath().ensure(dir=1) if encoding: - # Using type ignore here because of this error: - # error: Argument 1 has incompatible type overloaded function; - # expected "Callable[[str, Any, Any], TextIOWrapper]" [arg-type] - # Which seems incorrect, given io.open supports the given argument types. return error.checked_call( io.open, self.strpath, mode, - encoding=encoding, # type:ignore[arg-type] + encoding=encoding, ) return error.checked_call(open, self.strpath, mode) @@ -966,12 +961,10 @@ class LocalPath: return p @overload - def stat(self, raising: Literal[True] = ...) -> Stat: - ... + def stat(self, raising: Literal[True] = ...) -> Stat: ... @overload - def stat(self, raising: Literal[False]) -> Stat | None: - ... + def stat(self, raising: Literal[False]) -> Stat | None: ... def stat(self, raising: bool = True) -> Stat | None: """Return an os.stat() tuple.""" @@ -1277,13 +1270,7 @@ class LocalPath: if rootdir is None: rootdir = cls.get_temproot() - # Using type ignore here because of this error: - # error: Argument 1 has incompatible type overloaded function; expected "Callable[[str], str]" [arg-type] - # Which seems incorrect, given tempfile.mkdtemp supports the given argument types. - path = error.checked_call( - tempfile.mkdtemp, - dir=str(rootdir), # type:ignore[arg-type] - ) + path = error.checked_call(tempfile.mkdtemp, dir=str(rootdir)) return cls(path) @classmethod diff --git a/src/_pytest/assertion/__init__.py b/src/_pytest/assertion/__init__.py index ea71230e1..21dd4a4a4 100644 --- a/src/_pytest/assertion/__init__.py +++ b/src/_pytest/assertion/__init__.py @@ -1,5 +1,6 @@ # mypy: allow-untyped-defs """Support for presenting detailed information in failing assertions.""" + import sys from typing import Any from typing import Generator diff --git a/src/_pytest/assertion/rewrite.py b/src/_pytest/assertion/rewrite.py index ddae34c73..678471ee9 100644 --- a/src/_pytest/assertion/rewrite.py +++ b/src/_pytest/assertion/rewrite.py @@ -289,15 +289,13 @@ class AssertionRewritingHook(importlib.abc.MetaPathFinder, importlib.abc.Loader) else: from importlib.abc import TraversableResources - def get_resource_reader(self, name: str) -> TraversableResources: # type: ignore + def get_resource_reader(self, name: str) -> TraversableResources: if sys.version_info < (3, 11): from importlib.readers import FileReader else: from importlib.resources.readers import FileReader - return FileReader( # type:ignore[no-any-return] - types.SimpleNamespace(path=self._rewritten_names[name]) - ) + return FileReader(types.SimpleNamespace(path=self._rewritten_names[name])) def _write_pyc_fp( @@ -672,9 +670,9 @@ class AssertionRewriter(ast.NodeVisitor): self.enable_assertion_pass_hook = False self.source = source self.scope: tuple[ast.AST, ...] = () - self.variables_overwrite: defaultdict[ - tuple[ast.AST, ...], Dict[str, str] - ] = defaultdict(dict) + self.variables_overwrite: defaultdict[tuple[ast.AST, ...], Dict[str, str]] = ( + defaultdict(dict) + ) def run(self, mod: ast.Module) -> None: """Find all assert statements in *mod* and rewrite them.""" @@ -975,7 +973,7 @@ class AssertionRewriter(ast.NodeVisitor): # name if it's a local variable or _should_repr_global_name() # thinks it's acceptable. locs = ast.Call(self.builtin("locals"), [], []) - target_id = name.target.id # type: ignore[attr-defined] + target_id = name.target.id inlocs = ast.Compare(ast.Constant(target_id), [ast.In()], [locs]) dorepr = self.helper("_should_repr_global_name", name) test = ast.BoolOp(ast.Or(), [inlocs, dorepr]) diff --git a/src/_pytest/assertion/util.py b/src/_pytest/assertion/util.py index ca3df7490..cb6716410 100644 --- a/src/_pytest/assertion/util.py +++ b/src/_pytest/assertion/util.py @@ -1,5 +1,6 @@ # mypy: allow-untyped-defs """Utilities for assertion debugging.""" + import collections.abc import os import pprint @@ -222,10 +223,9 @@ def assertrepr_compare( except outcomes.Exit: raise except Exception: + repr_crash = _pytest._code.ExceptionInfo.from_current()._getreprcrash() explanation = [ - "(pytest_assertion plugin: representation of details failed: {}.".format( - _pytest._code.ExceptionInfo.from_current()._getreprcrash() - ), + f"(pytest_assertion plugin: representation of details failed: {repr_crash}.", " Probably an object has a faulty __repr__.)", ] diff --git a/src/_pytest/cacheprovider.py b/src/_pytest/cacheprovider.py index 5ccd2168d..81703ddac 100755 --- a/src/_pytest/cacheprovider.py +++ b/src/_pytest/cacheprovider.py @@ -1,5 +1,6 @@ # mypy: allow-untyped-defs """Implementation of the cache provider.""" + # This plugin was not named "cache" to avoid conflicts with the external # pytest-cache version. import dataclasses @@ -432,7 +433,7 @@ class NFPlugin: return res def _get_increasing_order(self, items: Iterable[nodes.Item]) -> List[nodes.Item]: - return sorted(items, key=lambda item: item.path.stat().st_mtime, reverse=True) # type: ignore[no-any-return] + return sorted(items, key=lambda item: item.path.stat().st_mtime, reverse=True) def pytest_sessionfinish(self) -> None: config = self.config diff --git a/src/_pytest/capture.py b/src/_pytest/capture.py index dce431c3d..3f6a25103 100644 --- a/src/_pytest/capture.py +++ b/src/_pytest/capture.py @@ -1,5 +1,6 @@ # mypy: allow-untyped-defs """Per-test stdout/stderr capturing mechanism.""" + import abc import collections import contextlib @@ -105,17 +106,16 @@ def _windowsconsoleio_workaround(stream: TextIO) -> None: return # Bail out if ``stream`` doesn't seem like a proper ``io`` stream (#2666). - if not hasattr(stream, "buffer"): # type: ignore[unreachable] + if not hasattr(stream, "buffer"): # type: ignore[unreachable,unused-ignore] return - buffered = hasattr(stream.buffer, "raw") - raw_stdout = stream.buffer.raw if buffered else stream.buffer # type: ignore[attr-defined] + raw_stdout = stream.buffer.raw if hasattr(stream.buffer, "raw") else stream.buffer - if not isinstance(raw_stdout, io._WindowsConsoleIO): # type: ignore[attr-defined] + if not isinstance(raw_stdout, io._WindowsConsoleIO): # type: ignore[attr-defined,unused-ignore] return def _reopen_stdio(f, mode): - if not buffered and mode[0] == "w": + if not hasattr(stream.buffer, "raw") and mode[0] == "w": buffering = 0 else: buffering = -1 @@ -482,12 +482,9 @@ class FDCaptureBase(CaptureBase[AnyStr]): self._state = "initialized" def __repr__(self) -> str: - return "<{} {} oldfd={} _state={!r} tmpfile={!r}>".format( - self.__class__.__name__, - self.targetfd, - self.targetfd_save, - self._state, - self.tmpfile, + return ( + f"<{self.__class__.__name__} {self.targetfd} oldfd={self.targetfd_save} " + f"_state={self._state!r} tmpfile={self.tmpfile!r}>" ) def _assert_state(self, op: str, states: Tuple[str, ...]) -> None: @@ -621,12 +618,9 @@ class MultiCapture(Generic[AnyStr]): self.err: Optional[CaptureBase[AnyStr]] = err def __repr__(self) -> str: - return "".format( - self.out, - self.err, - self.in_, - self._state, - self._in_suspended, + return ( + f"" ) def start_capturing(self) -> None: @@ -735,8 +729,9 @@ class CaptureManager: self._capture_fixture: Optional[CaptureFixture[Any]] = None def __repr__(self) -> str: - return "".format( - self._method, self._global_capturing, self._capture_fixture + return ( + f"" ) def is_capturing(self) -> Union[str, bool]: diff --git a/src/_pytest/compat.py b/src/_pytest/compat.py index 8d49d6fb6..9d9411818 100644 --- a/src/_pytest/compat.py +++ b/src/_pytest/compat.py @@ -304,7 +304,7 @@ def get_user_id() -> int | None: # mypy follows the version and platform checking expectation of PEP 484: # https://mypy.readthedocs.io/en/stable/common_issues.html?highlight=platform#python-version-and-system-platform-checks # Containment checks are too complex for mypy v1.5.0 and cause failure. - if sys.platform == "win32" or sys.platform == "emscripten": # noqa: PLR1714 + if sys.platform == "win32" or sys.platform == "emscripten": # win32 does not have a getuid() function. # Emscripten has a return 0 stub. return None diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index bf2cfc399..7ff27643f 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -1,5 +1,6 @@ # mypy: allow-untyped-defs """Command line options, ini-file and conftest.py processing.""" + import argparse import collections.abc import copy diff --git a/src/_pytest/config/argparsing.py b/src/_pytest/config/argparsing.py index 441d79e90..95dc28d4a 100644 --- a/src/_pytest/config/argparsing.py +++ b/src/_pytest/config/argparsing.py @@ -426,8 +426,7 @@ class MyOptionParser(argparse.ArgumentParser): msg = f"{self.prog}: error: {message}" if hasattr(self._parser, "_config_source_hint"): - # Type ignored because the attribute is set dynamically. - msg = f"{msg} ({self._parser._config_source_hint})" # type: ignore + msg = f"{msg} ({self._parser._config_source_hint})" raise UsageError(self.format_usage() + msg) diff --git a/src/_pytest/debugging.py b/src/_pytest/debugging.py index cb157cd67..6ed0c5c7a 100644 --- a/src/_pytest/debugging.py +++ b/src/_pytest/debugging.py @@ -1,5 +1,6 @@ # mypy: allow-untyped-defs """Interactive debugging with PDB, the Python Debugger.""" + import argparse import functools import sys @@ -154,9 +155,7 @@ class pytestPDB: def _get_pdb_wrapper_class(cls, pdb_cls, capman: Optional["CaptureManager"]): import _pytest.config - # Type ignored because mypy doesn't support "dynamic" - # inheritance like this. - class PytestPdbWrapper(pdb_cls): # type: ignore[valid-type,misc] + class PytestPdbWrapper(pdb_cls): _pytest_capman = capman _continued = False diff --git a/src/_pytest/doctest.py b/src/_pytest/doctest.py index ced3b82f5..7fff99f37 100644 --- a/src/_pytest/doctest.py +++ b/src/_pytest/doctest.py @@ -1,5 +1,6 @@ # mypy: allow-untyped-defs """Discover and run doctests in modules and test files.""" + import bdb from contextlib import contextmanager import functools diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py index daf3145aa..8b25d743c 100644 --- a/src/_pytest/fixtures.py +++ b/src/_pytest/fixtures.py @@ -447,7 +447,7 @@ class FixtureRequest(abc.ABC): @property def config(self) -> Config: """The pytest config object associated with this request.""" - return self._pyfuncitem.config # type: ignore[no-any-return] + return self._pyfuncitem.config @property def function(self): @@ -499,7 +499,7 @@ class FixtureRequest(abc.ABC): @property def session(self) -> "Session": """Pytest session object.""" - return self._pyfuncitem.session # type: ignore[no-any-return] + return self._pyfuncitem.session @abc.abstractmethod def addfinalizer(self, finalizer: Callable[[], object]) -> None: @@ -629,17 +629,14 @@ class FixtureRequest(abc.ABC): ) except ValueError: source_path_str = str(source_path) + location = getlocation(fixturedef.func, funcitem.config.rootpath) msg = ( "The requested fixture has no parameter defined for test:\n" - " {}\n\n" - "Requested fixture '{}' defined in:\n{}" - "\n\nRequested here:\n{}:{}".format( - funcitem.nodeid, - fixturedef.argname, - getlocation(fixturedef.func, funcitem.config.rootpath), - source_path_str, - source_lineno, - ) + f" {funcitem.nodeid}\n\n" + f"Requested fixture '{fixturedef.argname}' defined in:\n" + f"{location}\n\n" + f"Requested here:\n" + f"{source_path_str}:{source_lineno}" ) fail(msg, pytrace=False) @@ -1108,12 +1105,12 @@ def resolve_fixture_function( # (for example a plugin class with a fixture), see #2270. if hasattr(fixturefunc, "__self__") and not isinstance( instance, - fixturefunc.__self__.__class__, # type: ignore[union-attr] + fixturefunc.__self__.__class__, ): return fixturefunc fixturefunc = getimfunc(fixturedef.func) if fixturefunc != fixturedef.func: - fixturefunc = fixturefunc.__get__(instance) # type: ignore[union-attr] + fixturefunc = fixturefunc.__get__(instance) return fixturefunc @@ -1147,12 +1144,13 @@ def wrap_function_to_error_out_if_called_directly( ) -> FixtureFunction: """Wrap the given fixture function so we can raise an error about it being called directly, instead of used as an argument in a test function.""" + name = fixture_marker.name or function.__name__ message = ( - 'Fixture "{name}" called directly. Fixtures are not meant to be called directly,\n' + f'Fixture "{name}" called directly. Fixtures are not meant to be called directly,\n' "but are created automatically when test functions request them as parameters.\n" "See https://docs.pytest.org/en/stable/explanation/fixtures.html for more information about fixtures, and\n" "https://docs.pytest.org/en/stable/deprecations.html#calling-fixtures-directly about how to update your code." - ).format(name=fixture_marker.name or function.__name__) + ) @functools.wraps(function) def result(*args, **kwargs): @@ -1219,8 +1217,7 @@ def fixture( Union[Sequence[Optional[object]], Callable[[Any], Optional[object]]] ] = ..., name: Optional[str] = ..., -) -> FixtureFunction: - ... +) -> FixtureFunction: ... @overload @@ -1234,8 +1231,7 @@ def fixture( Union[Sequence[Optional[object]], Callable[[Any], Optional[object]]] ] = ..., name: Optional[str] = None, -) -> FixtureFunctionMarker: - ... +) -> FixtureFunctionMarker: ... def fixture( diff --git a/src/_pytest/freeze_support.py b/src/_pytest/freeze_support.py index d028058e3..e03a6d175 100644 --- a/src/_pytest/freeze_support.py +++ b/src/_pytest/freeze_support.py @@ -35,7 +35,7 @@ def _iter_all_modules( else: # Type ignored because typeshed doesn't define ModuleType.__path__ # (only defined on packages). - package_path = package.__path__ # type: ignore[attr-defined] + package_path = package.__path__ path, prefix = package_path[0], package.__name__ + "." for _, name, is_package in pkgutil.iter_modules([path]): if is_package: diff --git a/src/_pytest/helpconfig.py b/src/_pytest/helpconfig.py index aa8bf65c7..37fbdf04d 100644 --- a/src/_pytest/helpconfig.py +++ b/src/_pytest/helpconfig.py @@ -1,5 +1,6 @@ # mypy: allow-untyped-defs """Version info, help messages, tracing configuration.""" + from argparse import Action import os import sys diff --git a/src/_pytest/hookspec.py b/src/_pytest/hookspec.py index 4bee76f1e..db55bd82d 100644 --- a/src/_pytest/hookspec.py +++ b/src/_pytest/hookspec.py @@ -1,6 +1,7 @@ # mypy: allow-untyped-defs """Hook specifications for pytest plugins which are invoked by pytest itself and by builtin plugins.""" + from pathlib import Path from typing import Any from typing import Dict diff --git a/src/_pytest/junitxml.py b/src/_pytest/junitxml.py index 4ca356f31..e6ccebc20 100644 --- a/src/_pytest/junitxml.py +++ b/src/_pytest/junitxml.py @@ -7,6 +7,7 @@ Based on initial code from Ross Lawley. Output conforms to https://github.com/jenkinsci/xunit-plugin/blob/master/src/main/resources/org/jenkinsci/plugins/xunit/types/model/xsd/junit-10.xsd """ + from datetime import datetime import functools import os @@ -60,7 +61,7 @@ def bin_xml_escape(arg: object) -> str: # Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] # For an unknown(?) reason, we disallow #x7F (DEL) as well. illegal_xml_re = ( - "[^\u0009\u000A\u000D\u0020-\u007E\u0080-\uD7FF\uE000-\uFFFD\u10000-\u10FFFF]" + "[^\u0009\u000a\u000d\u0020-\u007e\u0080-\ud7ff\ue000-\ufffd\u10000-\u10ffff]" ) return re.sub(illegal_xml_re, repl, str(arg)) @@ -261,7 +262,7 @@ class _NodeReporter: self.__dict__.clear() # Type ignored because mypy doesn't like overriding a method. # Also the return value doesn't match... - self.to_xml = lambda: data # type: ignore[assignment] + self.to_xml = lambda: data # type: ignore[method-assign] def _warn_incompatibility_with_xunit2( diff --git a/src/_pytest/logging.py b/src/_pytest/logging.py index e9a3234fd..af5e443ce 100644 --- a/src/_pytest/logging.py +++ b/src/_pytest/logging.py @@ -1,5 +1,6 @@ # mypy: allow-untyped-defs """Access and control log capturing.""" + from contextlib import contextmanager from contextlib import nullcontext from datetime import datetime @@ -209,7 +210,7 @@ class PercentStyleMultiline(logging.PercentStyle): if "\n" in record.message: if hasattr(record, "auto_indent"): # Passed in from the "extra={}" kwarg on the call to logging.log(). - auto_indent = self._get_auto_indent(record.auto_indent) # type: ignore[attr-defined] + auto_indent = self._get_auto_indent(record.auto_indent) else: auto_indent = self._auto_indent @@ -512,7 +513,7 @@ class LogCaptureFixture: :return: The original disabled logging level. """ - original_disable_level: int = logger_obj.manager.disable # type: ignore[attr-defined] + original_disable_level: int = logger_obj.manager.disable if isinstance(level, str): # Try to translate the level string to an int for `logging.disable()` diff --git a/src/_pytest/main.py b/src/_pytest/main.py index 3b9ac93cf..716d5cf78 100644 --- a/src/_pytest/main.py +++ b/src/_pytest/main.py @@ -736,14 +736,12 @@ class Session(nodes.Collector): @overload def perform_collect( self, args: Optional[Sequence[str]] = ..., genitems: "Literal[True]" = ... - ) -> Sequence[nodes.Item]: - ... + ) -> Sequence[nodes.Item]: ... @overload def perform_collect( self, args: Optional[Sequence[str]] = ..., genitems: bool = ... - ) -> Sequence[Union[nodes.Item, nodes.Collector]]: - ... + ) -> Sequence[Union[nodes.Item, nodes.Collector]]: ... def perform_collect( self, args: Optional[Sequence[str]] = None, genitems: bool = True diff --git a/src/_pytest/mark/structures.py b/src/_pytest/mark/structures.py index 1da300c82..a6503bf1d 100644 --- a/src/_pytest/mark/structures.py +++ b/src/_pytest/mark/structures.py @@ -342,7 +342,7 @@ class MarkDecorator: # return type. Not much we can do about that. Thankfully mypy picks # the first match so it works out even if we break the rules. @overload - def __call__(self, arg: Markable) -> Markable: # type: ignore[misc] + def __call__(self, arg: Markable) -> Markable: # type: ignore[overload-overlap] pass @overload @@ -433,13 +433,11 @@ if TYPE_CHECKING: from _pytest.scope import _ScopeName class _SkipMarkDecorator(MarkDecorator): - @overload # type: ignore[override,misc,no-overload-impl] - def __call__(self, arg: Markable) -> Markable: - ... + @overload # type: ignore[override,no-overload-impl] + def __call__(self, arg: Markable) -> Markable: ... @overload - def __call__(self, reason: str = ...) -> "MarkDecorator": - ... + def __call__(self, reason: str = ...) -> "MarkDecorator": ... class _SkipifMarkDecorator(MarkDecorator): def __call__( # type: ignore[override] @@ -447,13 +445,11 @@ if TYPE_CHECKING: condition: Union[str, bool] = ..., *conditions: Union[str, bool], reason: str = ..., - ) -> MarkDecorator: - ... + ) -> MarkDecorator: ... class _XfailMarkDecorator(MarkDecorator): - @overload # type: ignore[override,misc,no-overload-impl] - def __call__(self, arg: Markable) -> Markable: - ... + @overload # type: ignore[override,no-overload-impl] + def __call__(self, arg: Markable) -> Markable: ... @overload def __call__( @@ -466,8 +462,7 @@ if TYPE_CHECKING: None, Type[BaseException], Tuple[Type[BaseException], ...] ] = ..., strict: bool = ..., - ) -> MarkDecorator: - ... + ) -> MarkDecorator: ... class _ParametrizeMarkDecorator(MarkDecorator): def __call__( # type: ignore[override] @@ -483,8 +478,7 @@ if TYPE_CHECKING: ] ] = ..., scope: Optional[_ScopeName] = ..., - ) -> MarkDecorator: - ... + ) -> MarkDecorator: ... class _UsefixturesMarkDecorator(MarkDecorator): def __call__(self, *fixtures: str) -> MarkDecorator: # type: ignore[override] diff --git a/src/_pytest/monkeypatch.py b/src/_pytest/monkeypatch.py index e96a93868..3f398df76 100644 --- a/src/_pytest/monkeypatch.py +++ b/src/_pytest/monkeypatch.py @@ -1,5 +1,6 @@ # mypy: allow-untyped-defs """Monkeypatching and mocking functionality.""" + from contextlib import contextmanager import os import re @@ -167,8 +168,7 @@ class MonkeyPatch: name: object, value: Notset = ..., raising: bool = ..., - ) -> None: - ... + ) -> None: ... @overload def setattr( @@ -177,8 +177,7 @@ class MonkeyPatch: name: str, value: object, raising: bool = ..., - ) -> None: - ... + ) -> None: ... def setattr( self, diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py index cff15001c..1b91bdb6e 100644 --- a/src/_pytest/nodes.py +++ b/src/_pytest/nodes.py @@ -363,12 +363,10 @@ class Node(abc.ABC, metaclass=NodeMeta): yield node, mark @overload - def get_closest_marker(self, name: str) -> Optional[Mark]: - ... + def get_closest_marker(self, name: str) -> Optional[Mark]: ... @overload - def get_closest_marker(self, name: str, default: Mark) -> Mark: - ... + def get_closest_marker(self, name: str, default: Mark) -> Mark: ... def get_closest_marker( self, name: str, default: Optional[Mark] = None diff --git a/src/_pytest/pastebin.py b/src/_pytest/pastebin.py index 98ba5c9c1..533d78c9a 100644 --- a/src/_pytest/pastebin.py +++ b/src/_pytest/pastebin.py @@ -1,5 +1,6 @@ # mypy: allow-untyped-defs """Submit failure or test session information to a pastebin service.""" + from io import StringIO import tempfile from typing import IO diff --git a/src/_pytest/pytester.py b/src/_pytest/pytester.py index 8002528b9..23f44da69 100644 --- a/src/_pytest/pytester.py +++ b/src/_pytest/pytester.py @@ -3,6 +3,7 @@ PYTEST_DONT_REWRITE """ + import collections.abc import contextlib from fnmatch import fnmatch @@ -245,8 +246,7 @@ class RecordedHookCall: if TYPE_CHECKING: # The class has undetermined attributes, this tells mypy about it. - def __getattr__(self, key: str): - ... + def __getattr__(self, key: str): ... @final @@ -327,15 +327,13 @@ class HookRecorder: def getreports( self, names: "Literal['pytest_collectreport']", - ) -> Sequence[CollectReport]: - ... + ) -> Sequence[CollectReport]: ... @overload def getreports( self, names: "Literal['pytest_runtest_logreport']", - ) -> Sequence[TestReport]: - ... + ) -> Sequence[TestReport]: ... @overload def getreports( @@ -344,8 +342,7 @@ class HookRecorder: "pytest_collectreport", "pytest_runtest_logreport", ), - ) -> Sequence[Union[CollectReport, TestReport]]: - ... + ) -> Sequence[Union[CollectReport, TestReport]]: ... def getreports( self, @@ -390,15 +387,13 @@ class HookRecorder: def getfailures( self, names: "Literal['pytest_collectreport']", - ) -> Sequence[CollectReport]: - ... + ) -> Sequence[CollectReport]: ... @overload def getfailures( self, names: "Literal['pytest_runtest_logreport']", - ) -> Sequence[TestReport]: - ... + ) -> Sequence[TestReport]: ... @overload def getfailures( @@ -407,8 +402,7 @@ class HookRecorder: "pytest_collectreport", "pytest_runtest_logreport", ), - ) -> Sequence[Union[CollectReport, TestReport]]: - ... + ) -> Sequence[Union[CollectReport, TestReport]]: ... def getfailures( self, diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 7b0683b6e..3242d517e 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -1,5 +1,6 @@ # mypy: allow-untyped-defs """Python test discovery, setup and run of test functions.""" + import abc from collections import Counter from collections import defaultdict diff --git a/src/_pytest/python_api.py b/src/_pytest/python_api.py index 7e51da319..0ba86e816 100644 --- a/src/_pytest/python_api.py +++ b/src/_pytest/python_api.py @@ -393,7 +393,7 @@ class ApproxScalar(ApproxBase): # tolerances, i.e. non-numerics and infinities. Need to call abs to # handle complex numbers, e.g. (inf + 1j). if (not isinstance(self.expected, (Complex, Decimal))) or math.isinf( - abs(self.expected) # type: ignore[arg-type] + abs(self.expected) ): return str(self.expected) @@ -437,8 +437,8 @@ class ApproxScalar(ApproxBase): # Allow the user to control whether NaNs are considered equal to each # other or not. The abs() calls are for compatibility with complex # numbers. - if math.isnan(abs(self.expected)): # type: ignore[arg-type] - return self.nan_ok and math.isnan(abs(actual)) # type: ignore[arg-type] + if math.isnan(abs(self.expected)): + return self.nan_ok and math.isnan(abs(actual)) # Infinity shouldn't be approximately equal to anything but itself, but # if there's a relative tolerance, it will be infinite and infinity @@ -446,11 +446,11 @@ class ApproxScalar(ApproxBase): # case would have been short circuited above, so here we can just # return false if the expected value is infinite. The abs() call is # for compatibility with complex numbers. - if math.isinf(abs(self.expected)): # type: ignore[arg-type] + if math.isinf(abs(self.expected)): return False # Return true if the two numbers are within the tolerance. - result: bool = abs(self.expected - actual) <= self.tolerance + result: bool = abs(self.expected - actual) <= self.tolerance # type: ignore[arg-type] return result # Ignore type because of https://github.com/python/mypy/issues/4266. @@ -769,8 +769,7 @@ def raises( expected_exception: Union[Type[E], Tuple[Type[E], ...]], *, match: Optional[Union[str, Pattern[str]]] = ..., -) -> "RaisesContext[E]": - ... +) -> "RaisesContext[E]": ... @overload @@ -779,8 +778,7 @@ def raises( func: Callable[..., Any], *args: Any, **kwargs: Any, -) -> _pytest._code.ExceptionInfo[E]: - ... +) -> _pytest._code.ExceptionInfo[E]: ... def raises( diff --git a/src/_pytest/recwarn.py b/src/_pytest/recwarn.py index bcf9f1466..63e7a4bd6 100644 --- a/src/_pytest/recwarn.py +++ b/src/_pytest/recwarn.py @@ -1,5 +1,6 @@ # mypy: allow-untyped-defs """Record warnings during test function execution.""" + from pprint import pformat import re from types import TracebackType @@ -43,13 +44,11 @@ def recwarn() -> Generator["WarningsRecorder", None, None]: @overload def deprecated_call( *, match: Optional[Union[str, Pattern[str]]] = ... -) -> "WarningsRecorder": - ... +) -> "WarningsRecorder": ... @overload -def deprecated_call(func: Callable[..., T], *args: Any, **kwargs: Any) -> T: - ... +def deprecated_call(func: Callable[..., T], *args: Any, **kwargs: Any) -> T: ... def deprecated_call( @@ -91,8 +90,7 @@ def warns( expected_warning: Union[Type[Warning], Tuple[Type[Warning], ...]] = ..., *, match: Optional[Union[str, Pattern[str]]] = ..., -) -> "WarningsChecker": - ... +) -> "WarningsChecker": ... @overload @@ -101,8 +99,7 @@ def warns( func: Callable[..., T], *args: Any, **kwargs: Any, -) -> T: - ... +) -> T: ... def warns( @@ -184,8 +181,7 @@ class WarningsRecorder(warnings.catch_warnings): # type:ignore[type-arg] def __init__(self, *, _ispytest: bool = False) -> None: check_ispytest(_ispytest) - # Type ignored due to the way typeshed handles warnings.catch_warnings. - super().__init__(record=True) # type: ignore[call-arg] + super().__init__(record=True) self._entered = False self._list: List[warnings.WarningMessage] = [] diff --git a/src/_pytest/reports.py b/src/_pytest/reports.py index 7cdb70e32..70f3212ce 100644 --- a/src/_pytest/reports.py +++ b/src/_pytest/reports.py @@ -72,8 +72,7 @@ class BaseReport: if TYPE_CHECKING: # Can have arbitrary fields given to __init__(). - def __getattr__(self, key: str) -> Any: - ... + def __getattr__(self, key: str) -> Any: ... def toterminal(self, out: TerminalWriter) -> None: if hasattr(self, "node"): @@ -606,9 +605,9 @@ def _report_kwargs_from_json(reportdict: Dict[str, Any]) -> Dict[str, Any]: description, ) ) - exception_info: Union[ - ExceptionChainRepr, ReprExceptionInfo - ] = ExceptionChainRepr(chain) + exception_info: Union[ExceptionChainRepr, ReprExceptionInfo] = ( + ExceptionChainRepr(chain) + ) else: exception_info = ReprExceptionInfo( reprtraceback=reprtraceback, diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index 16abb895d..3f706b927 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -1,5 +1,6 @@ # mypy: allow-untyped-defs """Basic collect and runtest protocol implementations.""" + import bdb import dataclasses import os @@ -84,7 +85,7 @@ def pytest_terminal_summary(terminalreporter: "TerminalReporter") -> None: dlist.append(rep) if not dlist: return - dlist.sort(key=lambda x: x.duration, reverse=True) # type: ignore[no-any-return] + dlist.sort(key=lambda x: x.duration, reverse=True) if not durations: tr.write_sep("=", "slowest durations") else: @@ -395,8 +396,7 @@ def pytest_make_collect_report(collector: Collector) -> CollectReport: skip_exceptions = [Skipped] unittest = sys.modules.get("unittest") if unittest is not None: - # Type ignored because unittest is loaded dynamically. - skip_exceptions.append(unittest.SkipTest) # type: ignore + skip_exceptions.append(unittest.SkipTest) if isinstance(call.excinfo.value, tuple(skip_exceptions)): outcome = "skipped" r_ = collector._repr_failure_py(call.excinfo, "line") diff --git a/src/_pytest/setuponly.py b/src/_pytest/setuponly.py index c87de1e32..39ab28b46 100644 --- a/src/_pytest/setuponly.py +++ b/src/_pytest/setuponly.py @@ -58,7 +58,7 @@ def pytest_fixture_post_finalizer( if config.option.setupshow: _show_fixture_action(fixturedef, request.config, "TEARDOWN") if hasattr(fixturedef, "cached_param"): - del fixturedef.cached_param # type: ignore[attr-defined] + del fixturedef.cached_param def _show_fixture_action( @@ -87,7 +87,7 @@ def _show_fixture_action( tw.write(" (fixtures used: {})".format(", ".join(deps))) if hasattr(fixturedef, "cached_param"): - tw.write(f"[{saferepr(fixturedef.cached_param, maxsize=42)}]") # type: ignore[attr-defined] + tw.write(f"[{saferepr(fixturedef.cached_param, maxsize=42)}]") tw.flush() diff --git a/src/_pytest/skipping.py b/src/_pytest/skipping.py index 4799ae649..188dcae3f 100644 --- a/src/_pytest/skipping.py +++ b/src/_pytest/skipping.py @@ -1,5 +1,6 @@ # mypy: allow-untyped-defs """Support for skip/xfail functions and markers.""" + from collections.abc import Mapping import dataclasses import os @@ -109,7 +110,7 @@ def evaluate_condition(item: Item, mark: Mark, condition: object) -> Tuple[bool, ) globals_.update(dictionary) if hasattr(item, "obj"): - globals_.update(item.obj.__globals__) # type: ignore[attr-defined] + globals_.update(item.obj.__globals__) try: filename = f"<{mark.name} condition>" condition_code = compile(condition, filename, "eval") diff --git a/src/_pytest/terminal.py b/src/_pytest/terminal.py index 75d57197a..2c9c0d3b1 100644 --- a/src/_pytest/terminal.py +++ b/src/_pytest/terminal.py @@ -3,6 +3,7 @@ This is a good source for looking at the various reporting hooks. """ + import argparse from collections import Counter import dataclasses diff --git a/src/_pytest/tmpdir.py b/src/_pytest/tmpdir.py index 1cb9fbbe0..72efed3e8 100644 --- a/src/_pytest/tmpdir.py +++ b/src/_pytest/tmpdir.py @@ -1,5 +1,6 @@ # mypy: allow-untyped-defs """Support for providing temporary directories to test functions.""" + import dataclasses import os from pathlib import Path diff --git a/src/_pytest/unittest.py b/src/_pytest/unittest.py index 32eb361c6..5099904fd 100644 --- a/src/_pytest/unittest.py +++ b/src/_pytest/unittest.py @@ -1,5 +1,6 @@ # mypy: allow-untyped-defs """Discover and run std-library "unittest" style tests.""" + import sys import traceback import types @@ -98,8 +99,7 @@ class UnitTestCase(Class): runtest = getattr(self.obj, "runTest", None) if runtest is not None: ut = sys.modules.get("twisted.trial.unittest", None) - # Type ignored because `ut` is an opaque module. - if ut is None or runtest != ut.TestCase.runTest: # type: ignore + if ut is None or runtest != ut.TestCase.runTest: yield TestCaseFunction.from_parent(self, name="runTest") def _register_unittest_setup_class_fixture(self, cls: type) -> None: @@ -302,8 +302,7 @@ class TestCaseFunction(Function): # Let the unittest framework handle async functions. if is_async_function(self.obj): - # Type ignored because self acts as the TestResult, but is not actually one. - testcase(result=self) # type: ignore[arg-type] + testcase(result=self) else: # When --pdb is given, we want to postpone calling tearDown() otherwise # when entering the pdb prompt, tearDown() would have probably cleaned up @@ -322,7 +321,7 @@ class TestCaseFunction(Function): # wrap_pytest_function_for_tracing replaces self.obj by a wrapper. setattr(testcase, self.name, self.obj) try: - testcase(result=self) # type: ignore[arg-type] + testcase(result=self) finally: delattr(testcase, self.name) @@ -353,9 +352,7 @@ def pytest_runtest_makereport(item: Item, call: CallInfo[None]) -> None: # its own nose.SkipTest. For unittest TestCases, SkipTest is already # handled internally, and doesn't reach here. unittest = sys.modules.get("unittest") - if ( - unittest and call.excinfo and isinstance(call.excinfo.value, unittest.SkipTest) # type: ignore[attr-defined] - ): + if unittest and call.excinfo and isinstance(call.excinfo.value, unittest.SkipTest): excinfo = call.excinfo call2 = CallInfo[None].from_call( lambda: pytest.skip(str(excinfo.value)), call.when diff --git a/src/pytest/__init__.py b/src/pytest/__init__.py index 20829aa58..c6b6de827 100644 --- a/src/pytest/__init__.py +++ b/src/pytest/__init__.py @@ -1,5 +1,6 @@ # PYTHON_ARGCOMPLETE_OK """pytest: unit and functional testing with Python.""" + from _pytest import __version__ from _pytest import version_tuple from _pytest._code import ExceptionInfo diff --git a/testing/_py/test_local.py b/testing/_py/test_local.py index 0c8575c4e..ad2526571 100644 --- a/testing/_py/test_local.py +++ b/testing/_py/test_local.py @@ -16,8 +16,8 @@ import pytest @contextlib.contextmanager def ignore_encoding_warning(): with warnings.catch_warnings(): - with contextlib.suppress(NameError): # new in 3.10 - warnings.simplefilter("ignore", EncodingWarning) # type: ignore [name-defined] + if sys.version_info > (3, 10): + warnings.simplefilter("ignore", EncodingWarning) yield @@ -822,7 +822,7 @@ class TestLocalPath(CommonFSTests): # depending on how the paths are used), but > 4096 (which is the # Linux' limitation) - the behaviour of paths with names > 4096 chars # is undetermined - newfilename = "/test" * 60 # type:ignore[unreachable] + newfilename = "/test" * 60 # type:ignore[unreachable,unused-ignore] l1 = tmpdir.join(newfilename) l1.ensure(file=True) l1.write_text("foo", encoding="utf-8") @@ -1368,8 +1368,8 @@ class TestPOSIXLocalPath: assert realpath.basename == "file" def test_owner(self, path1, tmpdir): - from grp import getgrgid # type:ignore[attr-defined] - from pwd import getpwuid # type:ignore[attr-defined] + from grp import getgrgid # type:ignore[attr-defined,unused-ignore] + from pwd import getpwuid # type:ignore[attr-defined,unused-ignore] stat = path1.stat() assert stat.path == path1 diff --git a/testing/code/test_excinfo.py b/testing/code/test_excinfo.py index 49c5dd371..419c11abc 100644 --- a/testing/code/test_excinfo.py +++ b/testing/code/test_excinfo.py @@ -180,7 +180,7 @@ class TestTraceback_f_g_h: def test_traceback_cut_excludepath(self, pytester: Pytester) -> None: p = pytester.makepyfile("def f(): raise ValueError") with pytest.raises(ValueError) as excinfo: - import_path(p, root=pytester.path, consider_namespace_packages=False).f() # type: ignore[attr-defined] + import_path(p, root=pytester.path, consider_namespace_packages=False).f() basedir = Path(pytest.__file__).parent newtraceback = excinfo.traceback.cut(excludepath=basedir) for x in newtraceback: diff --git a/testing/example_scripts/acceptance/fixture_mock_integration.py b/testing/example_scripts/acceptance/fixture_mock_integration.py index 36e711f40..d802a7f87 100644 --- a/testing/example_scripts/acceptance/fixture_mock_integration.py +++ b/testing/example_scripts/acceptance/fixture_mock_integration.py @@ -1,5 +1,6 @@ # mypy: allow-untyped-defs """Reproduces issue #3774""" + from unittest import mock import pytest diff --git a/testing/example_scripts/unittest/test_setup_skip.py b/testing/example_scripts/unittest/test_setup_skip.py index 4681cda03..7550a0975 100644 --- a/testing/example_scripts/unittest/test_setup_skip.py +++ b/testing/example_scripts/unittest/test_setup_skip.py @@ -1,5 +1,6 @@ # mypy: allow-untyped-defs """Skipping an entire subclass with unittest.skip() should *not* call setUp from a base class.""" + import unittest diff --git a/testing/example_scripts/unittest/test_setup_skip_class.py b/testing/example_scripts/unittest/test_setup_skip_class.py index eae98287f..48f7e476f 100644 --- a/testing/example_scripts/unittest/test_setup_skip_class.py +++ b/testing/example_scripts/unittest/test_setup_skip_class.py @@ -1,5 +1,6 @@ # mypy: allow-untyped-defs """Skipping an entire subclass with unittest.skip() should *not* call setUpClass from a base class.""" + import unittest diff --git a/testing/example_scripts/unittest/test_setup_skip_module.py b/testing/example_scripts/unittest/test_setup_skip_module.py index 43c24136e..eee4263d2 100644 --- a/testing/example_scripts/unittest/test_setup_skip_module.py +++ b/testing/example_scripts/unittest/test_setup_skip_module.py @@ -1,5 +1,6 @@ # mypy: allow-untyped-defs """setUpModule is always called, even if all tests in the module are skipped""" + import unittest diff --git a/testing/example_scripts/unittest/test_unittest_asynctest.py b/testing/example_scripts/unittest/test_unittest_asynctest.py index b3f03e325..e9b10171e 100644 --- a/testing/example_scripts/unittest/test_unittest_asynctest.py +++ b/testing/example_scripts/unittest/test_unittest_asynctest.py @@ -1,5 +1,6 @@ # mypy: allow-untyped-defs """Issue #7110""" + import asyncio from typing import List diff --git a/testing/io/test_wcwidth.py b/testing/io/test_wcwidth.py index 0989af00d..82503b830 100644 --- a/testing/io/test_wcwidth.py +++ b/testing/io/test_wcwidth.py @@ -11,8 +11,8 @@ import pytest ("a", 1), ("1", 1), ("א", 1), - ("\u200B", 0), - ("\u1ABE", 0), + ("\u200b", 0), + ("\u1abe", 0), ("\u0591", 0), ("🉐", 2), ("$", 2), # noqa: RUF001 diff --git a/testing/python/metafunc.py b/testing/python/metafunc.py index ed22c2b5a..3d0058fa0 100644 --- a/testing/python/metafunc.py +++ b/testing/python/metafunc.py @@ -109,7 +109,7 @@ class TestMetafunc: metafunc = self.Metafunc(func) # When the input is an iterator, only len(args) are taken, # so the bad Exc isn't reached. - metafunc.parametrize("x", [1, 2], ids=gen()) # type: ignore[arg-type] + metafunc.parametrize("x", [1, 2], ids=gen()) assert [(x.params, x.id) for x in metafunc._calls] == [ ({"x": 1}, "0"), ({"x": 2}, "2"), @@ -121,7 +121,7 @@ class TestMetafunc: r"Supported types are: .*" ), ): - metafunc.parametrize("x", [1, 2, 3], ids=gen()) # type: ignore[arg-type] + metafunc.parametrize("x", [1, 2, 3], ids=gen()) def test_parametrize_bad_scope(self) -> None: def func(x): diff --git a/testing/test_config.py b/testing/test_config.py index 88470ff2d..147c2cb85 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -1243,7 +1243,7 @@ def test_disable_plugin_autoload( monkeypatch.setenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", "1") monkeypatch.setattr(importlib.metadata, "distributions", distributions) - monkeypatch.setitem(sys.modules, "mytestplugin", PseudoPlugin()) # type: ignore[misc] + monkeypatch.setitem(sys.modules, "mytestplugin", PseudoPlugin()) config = pytester.parseconfig(*parse_args) has_loaded = config.pluginmanager.get_plugin("mytestplugin") is not None assert has_loaded == should_load diff --git a/testing/test_debugging.py b/testing/test_debugging.py index 91a0be481..53ebadbdb 100644 --- a/testing/test_debugging.py +++ b/testing/test_debugging.py @@ -29,7 +29,7 @@ def runpdb_and_get_stdout(pytester: Pytester, source: str): def runpdb_and_get_report(pytester: Pytester, source: str): result = runpdb(pytester, source) - reports = result.reprec.getreports("pytest_runtest_logreport") # type: ignore[attr-defined] + reports = result.reprec.getreports("pytest_runtest_logreport") assert len(reports) == 3, reports # setup/call/teardown return reports[1] diff --git a/testing/test_junitxml.py b/testing/test_junitxml.py index 42104255b..3b92d65bd 100644 --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -1202,7 +1202,7 @@ def test_unicode_issue368(pytester: Pytester) -> None: node_reporter.append_skipped(test_report) test_report.longrepr = "filename", 1, "Skipped: 卡嘣嘣" node_reporter.append_skipped(test_report) - test_report.wasxfail = ustr # type: ignore[attr-defined] + test_report.wasxfail = ustr node_reporter.append_skipped(test_report) log.pytest_sessionfinish() diff --git a/testing/test_mark.py b/testing/test_mark.py index 6e183a178..2896afa45 100644 --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -18,7 +18,7 @@ class TestMark: @pytest.mark.parametrize("attr", ["mark", "param"]) def test_pytest_exists_in_namespace_all(self, attr: str) -> None: module = sys.modules["pytest"] - assert attr in module.__all__ # type: ignore + assert attr in module.__all__ def test_pytest_mark_notcallable(self) -> None: mark = MarkGenerator(_ispytest=True) @@ -34,7 +34,7 @@ class TestMark: assert pytest.mark.foo(some_function) is some_function marked_with_args = pytest.mark.foo.with_args(some_function) - assert marked_with_args is not some_function # type: ignore[comparison-overlap] + assert marked_with_args is not some_function assert pytest.mark.foo(SomeClass) is SomeClass assert pytest.mark.foo.with_args(SomeClass) is not SomeClass # type: ignore[comparison-overlap] diff --git a/testing/test_pathlib.py b/testing/test_pathlib.py index a4bccb1b2..7f740a060 100644 --- a/testing/test_pathlib.py +++ b/testing/test_pathlib.py @@ -183,7 +183,7 @@ class TestImportPath: obj = import_path( path1 / "execfile.py", root=path1, consider_namespace_packages=ns_param ) - assert obj.x == 42 # type: ignore[attr-defined] + assert obj.x == 42 assert obj.__name__ == "execfile" def test_import_path_missing_file(self, path1: Path, ns_param: bool) -> None: @@ -246,7 +246,7 @@ class TestImportPath: mod = import_path( otherdir / "a.py", root=path1, consider_namespace_packages=ns_param ) - assert mod.result == "got it" # type: ignore[attr-defined] + assert mod.result == "got it" assert mod.__name__ == "otherdir.a" def test_b(self, path1: Path, ns_param: bool) -> None: @@ -254,7 +254,7 @@ class TestImportPath: mod = import_path( otherdir / "b.py", root=path1, consider_namespace_packages=ns_param ) - assert mod.stuff == "got it" # type: ignore[attr-defined] + assert mod.stuff == "got it" assert mod.__name__ == "otherdir.b" def test_c(self, path1: Path, ns_param: bool) -> None: @@ -262,14 +262,14 @@ class TestImportPath: mod = import_path( otherdir / "c.py", root=path1, consider_namespace_packages=ns_param ) - assert mod.value == "got it" # type: ignore[attr-defined] + assert mod.value == "got it" def test_d(self, path1: Path, ns_param: bool) -> None: otherdir = path1 / "otherdir" mod = import_path( otherdir / "d.py", root=path1, consider_namespace_packages=ns_param ) - assert mod.value2 == "got it" # type: ignore[attr-defined] + assert mod.value2 == "got it" def test_import_after(self, tmp_path: Path, ns_param: bool) -> None: tmp_path.joinpath("xxxpackage").mkdir() @@ -360,7 +360,7 @@ class TestImportPath: root=tmp_path, consider_namespace_packages=ns_param, ) - assert module.foo(2) == 42 # type: ignore[attr-defined] + assert module.foo(2) == 42 assert str(simple_module.parent) not in sys.path assert module.__name__ in sys.modules assert module.__name__ == f"_src.tests.mymod_{request.node.name}" @@ -400,7 +400,7 @@ class TestImportPath: root=tmp_path, consider_namespace_packages=ns_param, ) - assert module.foo(2) == 42 # type: ignore[attr-defined] + assert module.foo(2) == 42 # mode='importlib' fails if no spec is found to load the module import importlib.util diff --git a/testing/test_reports.py b/testing/test_reports.py index 2de5ae600..c6baeebc9 100644 --- a/testing/test_reports.py +++ b/testing/test_reports.py @@ -294,9 +294,9 @@ class TestReportSerialization: reprec = pytester.inline_run() if report_class is TestReport: - reports: Union[ - Sequence[TestReport], Sequence[CollectReport] - ] = reprec.getreports("pytest_runtest_logreport") + reports: Union[Sequence[TestReport], Sequence[CollectReport]] = ( + reprec.getreports("pytest_runtest_logreport") + ) # we have 3 reports: setup/call/teardown assert len(reports) == 3 # get the call report diff --git a/testing/test_runner_xunit.py b/testing/test_runner_xunit.py index 8076e20bc..587c9eb9f 100644 --- a/testing/test_runner_xunit.py +++ b/testing/test_runner_xunit.py @@ -1,5 +1,6 @@ # mypy: allow-untyped-defs """Test correct setup/teardowns at module, class, and instance level.""" + from typing import List from _pytest.pytester import Pytester diff --git a/testing/test_terminal.py b/testing/test_terminal.py index b311d6c9b..f49425109 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -1,5 +1,6 @@ # mypy: allow-untyped-defs """Terminal reporting of the full testing process.""" + from io import StringIO import os from pathlib import Path diff --git a/testing/typing_checks.py b/testing/typing_checks.py index a2ceabcbd..4b146a251 100644 --- a/testing/typing_checks.py +++ b/testing/typing_checks.py @@ -4,6 +4,7 @@ This file is not executed, it is only checked by mypy to ensure that none of the code triggers any mypy errors. """ + import contextlib from typing import Optional