From c07bbdfa5bc39b20ddc529fed83f3a405354ca75 Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Tue, 4 Jun 2024 23:29:14 +0300 Subject: [PATCH] Avoid some TYPE_CHECKING It's better not to use it when possible. --- src/_pytest/_code/code.py | 12 ++++++------ src/_pytest/config/__init__.py | 17 ++++++++--------- src/_pytest/debugging.py | 14 +++++--------- src/_pytest/fixtures.py | 2 +- src/_pytest/main.py | 5 +++-- src/_pytest/mark/structures.py | 2 +- src/_pytest/nodes.py | 6 +++--- src/_pytest/stepwise.py | 7 +------ src/_pytest/unittest.py | 17 +++++++++-------- testing/code/test_excinfo.py | 6 +++--- 10 files changed, 40 insertions(+), 48 deletions(-) diff --git a/src/_pytest/_code/code.py b/src/_pytest/_code/code.py index b1ef9fe22..b6e06340d 100644 --- a/src/_pytest/_code/code.py +++ b/src/_pytest/_code/code.py @@ -55,7 +55,7 @@ from _pytest.pathlib import bestrelpath if sys.version_info < (3, 11): from exceptiongroup import BaseExceptionGroup -_TracebackStyle = Literal["long", "short", "line", "no", "native", "value", "auto"] +TracebackStyle = Literal["long", "short", "line", "no", "native", "value", "auto"] class Code: @@ -628,7 +628,7 @@ class ExceptionInfo(Generic[E]): def getrepr( self, showlocals: bool = False, - style: _TracebackStyle = "long", + style: TracebackStyle = "long", abspath: bool = False, tbfilter: Union[ bool, Callable[["ExceptionInfo[BaseException]"], Traceback] @@ -809,7 +809,7 @@ class FormattedExcinfo: fail_marker: ClassVar = "E" showlocals: bool = False - style: _TracebackStyle = "long" + style: TracebackStyle = "long" abspath: bool = True tbfilter: Union[bool, Callable[[ExceptionInfo[BaseException]], Traceback]] = True funcargs: bool = False @@ -1174,7 +1174,7 @@ class ReprExceptionInfo(ExceptionRepr): class ReprTraceback(TerminalRepr): reprentries: Sequence[Union["ReprEntry", "ReprEntryNative"]] extraline: Optional[str] - style: _TracebackStyle + style: TracebackStyle entrysep: ClassVar = "_ " @@ -1208,7 +1208,7 @@ class ReprTracebackNative(ReprTraceback): class ReprEntryNative(TerminalRepr): lines: Sequence[str] - style: ClassVar[_TracebackStyle] = "native" + style: ClassVar[TracebackStyle] = "native" def toterminal(self, tw: TerminalWriter) -> None: tw.write("".join(self.lines)) @@ -1220,7 +1220,7 @@ class ReprEntry(TerminalRepr): reprfuncargs: Optional["ReprFuncArgs"] reprlocals: Optional["ReprLocals"] reprfileloc: Optional["ReprFileLocation"] - style: _TracebackStyle + style: TracebackStyle def _write_entry_lines(self, tw: TerminalWriter) -> None: """Write the source code portions of a list of traceback entries with syntax highlighting. diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index f3d3b3062..287fac463 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -54,7 +54,10 @@ from _pytest import __version__ import _pytest._code from _pytest._code import ExceptionInfo from _pytest._code import filter_traceback +from _pytest._code.code import TracebackStyle from _pytest._io import TerminalWriter +from _pytest.config.argparsing import Argument +from _pytest.config.argparsing import Parser import _pytest.deprecated import _pytest.hookspec from _pytest.outcomes import fail @@ -71,9 +74,7 @@ from _pytest.warning_types import warn_explicit_for if TYPE_CHECKING: - from .argparsing import Argument - from .argparsing import Parser - from _pytest._code.code import _TracebackStyle + from _pytest.cacheprovider import Cache from _pytest.terminal import TerminalReporter @@ -1030,6 +1031,9 @@ class Config: #: 'testpaths' configuration value. TESTPATHS = enum.auto() + # Set by cacheprovider plugin. + cache: Optional["Cache"] + def __init__( self, pluginmanager: PytestPluginManager, @@ -1091,11 +1095,6 @@ class Config: self.args_source = Config.ArgsSource.ARGS self.args: List[str] = [] - if TYPE_CHECKING: - from _pytest.cacheprovider import Cache - - self.cache: Optional[Cache] = None - @property def rootpath(self) -> Path: """The path to the :ref:`rootdir `. @@ -1175,7 +1174,7 @@ class Config: option: Optional[argparse.Namespace] = None, ) -> None: if option and getattr(option, "fulltrace", False): - style: _TracebackStyle = "long" + style: TracebackStyle = "long" else: style = "native" excrepr = excinfo.getrepr( diff --git a/src/_pytest/debugging.py b/src/_pytest/debugging.py index 1338ef9f2..eacb2836d 100644 --- a/src/_pytest/debugging.py +++ b/src/_pytest/debugging.py @@ -13,12 +13,12 @@ from typing import List from typing import Optional from typing import Tuple from typing import Type -from typing import TYPE_CHECKING from typing import Union import unittest from _pytest import outcomes from _pytest._code import ExceptionInfo +from _pytest.capture import CaptureManager from _pytest.config import Config from _pytest.config import ConftestImportFailure from _pytest.config import hookimpl @@ -27,11 +27,7 @@ from _pytest.config.argparsing import Parser from _pytest.config.exceptions import UsageError from _pytest.nodes import Node from _pytest.reports import BaseReport - - -if TYPE_CHECKING: - from _pytest.capture import CaptureManager - from _pytest.runner import CallInfo +from _pytest.runner import CallInfo def _validate_usepdb_cls(value: str) -> Tuple[str, str]: @@ -310,7 +306,7 @@ class PdbTrace: return (yield) -def wrap_pytest_function_for_tracing(pyfuncitem): +def wrap_pytest_function_for_tracing(pyfuncitem) -> None: """Change the Python function object of the given Function item by a wrapper which actually enters pdb before calling the python function itself, effectively leaving the user in the pdb prompt in the first @@ -322,14 +318,14 @@ def wrap_pytest_function_for_tracing(pyfuncitem): # python < 3.7.4) runcall's first param is `func`, which means we'd get # an exception if one of the kwargs to testfunction was called `func`. @functools.wraps(testfunction) - def wrapper(*args, **kwargs): + def wrapper(*args, **kwargs) -> None: func = functools.partial(testfunction, *args, **kwargs) _pdb.runcall(func) pyfuncitem.obj = wrapper -def maybe_wrap_pytest_function_for_tracing(pyfuncitem): +def maybe_wrap_pytest_function_for_tracing(pyfuncitem) -> None: """Wrap the given pytestfunct item for tracing support if --trace was given in the command line.""" if pyfuncitem.config.getvalue("trace"): diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py index 353082c17..93c8bc669 100644 --- a/src/_pytest/fixtures.py +++ b/src/_pytest/fixtures.py @@ -60,6 +60,7 @@ from _pytest.config.argparsing import Parser from _pytest.deprecated import check_ispytest from _pytest.deprecated import MARKED_FIXTURE from _pytest.deprecated import YIELD_FIXTURE +from _pytest.main import Session from _pytest.mark import Mark from _pytest.mark import ParameterSet from _pytest.mark.structures import MarkDecorator @@ -78,7 +79,6 @@ if sys.version_info < (3, 11): if TYPE_CHECKING: - from _pytest.main import Session from _pytest.python import CallSpec2 from _pytest.python import Function from _pytest.python import Metafunc diff --git a/src/_pytest/main.py b/src/_pytest/main.py index 716d5cf78..d200a6877 100644 --- a/src/_pytest/main.py +++ b/src/_pytest/main.py @@ -38,7 +38,6 @@ from _pytest.config import PytestPluginManager from _pytest.config import UsageError from _pytest.config.argparsing import Parser from _pytest.config.compat import PathAwareHookProxy -from _pytest.fixtures import FixtureManager from _pytest.outcomes import exit from _pytest.pathlib import absolutepath from _pytest.pathlib import bestrelpath @@ -55,6 +54,8 @@ from _pytest.warning_types import PytestWarning if TYPE_CHECKING: from typing import Self + from _pytest.fixtures import FixtureManager + def pytest_addoption(parser: Parser) -> None: parser.addini( @@ -551,7 +552,7 @@ class Session(nodes.Collector): # Set on the session by runner.pytest_sessionstart. _setupstate: SetupState # Set on the session by fixtures.pytest_sessionstart. - _fixturemanager: FixtureManager + _fixturemanager: "FixtureManager" exitstatus: Union[int, ExitCode] def __init__(self, config: Config) -> None: diff --git a/src/_pytest/mark/structures.py b/src/_pytest/mark/structures.py index 3567142a6..456808063 100644 --- a/src/_pytest/mark/structures.py +++ b/src/_pytest/mark/structures.py @@ -31,6 +31,7 @@ from _pytest.config import Config from _pytest.deprecated import check_ispytest from _pytest.deprecated import MARKED_FIXTURE from _pytest.outcomes import fail +from _pytest.scope import _ScopeName from _pytest.warning_types import PytestUnknownMarkWarning @@ -430,7 +431,6 @@ def store_mark(obj, mark: Mark, *, stacklevel: int = 2) -> None: # Typing for builtin pytest marks. This is cheating; it gives builtin marks # special privilege, and breaks modularity. But practicality beats purity... if TYPE_CHECKING: - from _pytest.scope import _ScopeName class _SkipMarkDecorator(MarkDecorator): @overload # type: ignore[override,no-overload-impl] diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py index e73101971..aad54f8b3 100644 --- a/src/_pytest/nodes.py +++ b/src/_pytest/nodes.py @@ -30,6 +30,7 @@ from _pytest._code import getfslineno from _pytest._code.code import ExceptionInfo from _pytest._code.code import TerminalRepr from _pytest._code.code import Traceback +from _pytest._code.code import TracebackStyle from _pytest.compat import LEGACY_PATH from _pytest.config import Config from _pytest.config import ConftestImportFailure @@ -49,7 +50,6 @@ if TYPE_CHECKING: from typing import Self # Imported here due to circular import. - from _pytest._code.code import _TracebackStyle from _pytest.main import Session @@ -416,7 +416,7 @@ class Node(abc.ABC, metaclass=NodeMeta): def _repr_failure_py( self, excinfo: ExceptionInfo[BaseException], - style: "Optional[_TracebackStyle]" = None, + style: "Optional[TracebackStyle]" = None, ) -> TerminalRepr: from _pytest.fixtures import FixtureLookupError @@ -474,7 +474,7 @@ class Node(abc.ABC, metaclass=NodeMeta): def repr_failure( self, excinfo: ExceptionInfo[BaseException], - style: "Optional[_TracebackStyle]" = None, + style: "Optional[TracebackStyle]" = None, ) -> Union[str, TerminalRepr]: """Return a representation of a collection or test failure. diff --git a/src/_pytest/stepwise.py b/src/_pytest/stepwise.py index 92d3a297e..1e3a09d96 100644 --- a/src/_pytest/stepwise.py +++ b/src/_pytest/stepwise.py @@ -1,18 +1,14 @@ from typing import List from typing import Optional -from typing import TYPE_CHECKING from _pytest import nodes +from _pytest.cacheprovider import Cache from _pytest.config import Config from _pytest.config.argparsing import Parser from _pytest.main import Session from _pytest.reports import TestReport -import pytest -if TYPE_CHECKING: - from _pytest.cacheprovider import Cache - STEPWISE_CACHE_DIR = "cache/stepwise" @@ -37,7 +33,6 @@ def pytest_addoption(parser: Parser) -> None: ) -@pytest.hookimpl def pytest_configure(config: Config) -> None: if config.option.stepwise_skip: # allow --stepwise-skip to work on its own merits. diff --git a/src/_pytest/unittest.py b/src/_pytest/unittest.py index 643443f08..56a9c5d09 100644 --- a/src/_pytest/unittest.py +++ b/src/_pytest/unittest.py @@ -41,10 +41,11 @@ if TYPE_CHECKING: import twisted.trial.unittest - _SysExcInfoType = Union[ - Tuple[Type[BaseException], BaseException, types.TracebackType], - Tuple[None, None, None], - ] + +_SysExcInfoType = Union[ + Tuple[Type[BaseException], BaseException, types.TracebackType], + Tuple[None, None, None], +] def pytest_pycollect_makeitem( @@ -228,7 +229,7 @@ class TestCaseFunction(Function): def startTest(self, testcase: "unittest.TestCase") -> None: pass - def _addexcinfo(self, rawexcinfo: "_SysExcInfoType") -> None: + def _addexcinfo(self, rawexcinfo: _SysExcInfoType) -> None: # Unwrap potential exception info (see twisted trial support below). rawexcinfo = getattr(rawexcinfo, "_rawexcinfo", rawexcinfo) try: @@ -264,7 +265,7 @@ class TestCaseFunction(Function): self.__dict__.setdefault("_excinfo", []).append(excinfo) def addError( - self, testcase: "unittest.TestCase", rawexcinfo: "_SysExcInfoType" + self, testcase: "unittest.TestCase", rawexcinfo: _SysExcInfoType ) -> None: try: if isinstance(rawexcinfo[1], exit.Exception): @@ -274,7 +275,7 @@ class TestCaseFunction(Function): self._addexcinfo(rawexcinfo) def addFailure( - self, testcase: "unittest.TestCase", rawexcinfo: "_SysExcInfoType" + self, testcase: "unittest.TestCase", rawexcinfo: _SysExcInfoType ) -> None: self._addexcinfo(rawexcinfo) @@ -287,7 +288,7 @@ class TestCaseFunction(Function): def addExpectedFailure( self, testcase: "unittest.TestCase", - rawexcinfo: "_SysExcInfoType", + rawexcinfo: _SysExcInfoType, reason: str = "", ) -> None: try: diff --git a/testing/code/test_excinfo.py b/testing/code/test_excinfo.py index f7f780e98..fc60ae9ac 100644 --- a/testing/code/test_excinfo.py +++ b/testing/code/test_excinfo.py @@ -28,7 +28,7 @@ import pytest if TYPE_CHECKING: - from _pytest._code.code import _TracebackStyle + from _pytest._code.code import TracebackStyle if sys.version_info < (3, 11): from exceptiongroup import ExceptionGroup @@ -925,7 +925,7 @@ raise ValueError() ) excinfo = pytest.raises(ValueError, mod.entry) - styles: tuple[_TracebackStyle, ...] = ("long", "short") + styles: tuple[TracebackStyle, ...] = ("long", "short") for style in styles: p = FormattedExcinfo(style=style) reprtb = p.repr_traceback(excinfo) @@ -1052,7 +1052,7 @@ raise ValueError() ) excinfo = pytest.raises(ValueError, mod.entry) - styles: tuple[_TracebackStyle, ...] = ("short", "long", "no") + styles: tuple[TracebackStyle, ...] = ("short", "long", "no") for style in styles: for showlocals in (True, False): repr = excinfo.getrepr(style=style, showlocals=showlocals)