diff options
author | Ran Benita <ran@unusedvar.com> | 2020-12-26 21:23:23 +0200 |
---|---|---|
committer | Ran Benita <ran@unusedvar.com> | 2020-12-26 21:38:37 +0200 |
commit | 96ea867fec556a8d0e2b60392927572da38c88df (patch) | |
tree | b707a925e9f7655ae157da7927df80c4855d8e62 /src | |
parent | bd76042344b3c3318dddf991c08d49bbce2251bb (diff) | |
download | pytest-96ea867fec556a8d0e2b60392927572da38c88df.tar.gz |
runner: export pytest.CallInfo for typing purposes
The type cannot be constructed directly, but is exported for use in type
annotations, since it is reachable through existing public API.
This also documents `from_call` as public, because at least
pytest-forked uses it, so we must treat it as public already anyway.
Diffstat (limited to 'src')
-rw-r--r-- | src/_pytest/runner.py | 73 | ||||
-rw-r--r-- | src/pytest/__init__.py | 2 |
2 files changed, 51 insertions, 24 deletions
diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index 794690ddb..df046a78a 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -26,6 +26,7 @@ from _pytest._code.code import ExceptionInfo from _pytest._code.code import TerminalRepr from _pytest.compat import final from _pytest.config.argparsing import Parser +from _pytest.deprecated import check_ispytest from _pytest.nodes import Collector from _pytest.nodes import Item from _pytest.nodes import Node @@ -260,34 +261,47 @@ TResult = TypeVar("TResult", covariant=True) @final -@attr.s(repr=False) +@attr.s(repr=False, init=False, auto_attribs=True) class CallInfo(Generic[TResult]): - """Result/Exception info a function invocation. - - :param T result: - The return value of the call, if it didn't raise. Can only be - accessed if excinfo is None. - :param Optional[ExceptionInfo] excinfo: - The captured exception of the call, if it raised. - :param float start: - The system time when the call started, in seconds since the epoch. - :param float stop: - The system time when the call ended, in seconds since the epoch. - :param float duration: - The call duration, in seconds. - :param str when: - The context of invocation: "setup", "call", "teardown", ... - """ - - _result = attr.ib(type="Optional[TResult]") - excinfo = attr.ib(type=Optional[ExceptionInfo[BaseException]]) - start = attr.ib(type=float) - stop = attr.ib(type=float) - duration = attr.ib(type=float) - when = attr.ib(type="Literal['collect', 'setup', 'call', 'teardown']") + """Result/Exception info of a function invocation.""" + + _result: Optional[TResult] + #: The captured exception of the call, if it raised. + excinfo: Optional[ExceptionInfo[BaseException]] + #: The system time when the call started, in seconds since the epoch. + start: float + #: The system time when the call ended, in seconds since the epoch. + stop: float + #: The call duration, in seconds. + duration: float + #: The context of invocation: "collect", "setup", "call" or "teardown". + when: "Literal['collect', 'setup', 'call', 'teardown']" + + def __init__( + self, + result: Optional[TResult], + excinfo: Optional[ExceptionInfo[BaseException]], + start: float, + stop: float, + duration: float, + when: "Literal['collect', 'setup', 'call', 'teardown']", + *, + _ispytest: bool = False, + ) -> None: + check_ispytest(_ispytest) + self._result = result + self.excinfo = excinfo + self.start = start + self.stop = stop + self.duration = duration + self.when = when @property def result(self) -> TResult: + """The return value of the call, if it didn't raise. + + Can only be accessed if excinfo is None. + """ if self.excinfo is not None: raise AttributeError(f"{self!r} has no valid result") # The cast is safe because an exception wasn't raised, hence @@ -304,6 +318,16 @@ class CallInfo(Generic[TResult]): Union[Type[BaseException], Tuple[Type[BaseException], ...]] ] = None, ) -> "CallInfo[TResult]": + """Call func, wrapping the result in a CallInfo. + + :param func: + The function to call. Called without arguments. + :param when: + The phase in which the function is called. + :param reraise: + Exception or exceptions that shall propagate if raised by the + function, instead of being wrapped in the CallInfo. + """ excinfo = None start = timing.time() precise_start = timing.perf_counter() @@ -325,6 +349,7 @@ class CallInfo(Generic[TResult]): when=when, result=result, excinfo=excinfo, + _ispytest=True, ) def __repr__(self) -> str: diff --git a/src/pytest/__init__.py b/src/pytest/__init__.py index f97b0ac2e..53917340f 100644 --- a/src/pytest/__init__.py +++ b/src/pytest/__init__.py @@ -48,6 +48,7 @@ from _pytest.python_api import raises from _pytest.recwarn import deprecated_call from _pytest.recwarn import WarningsRecorder from _pytest.recwarn import warns +from _pytest.runner import CallInfo from _pytest.tmpdir import TempdirFactory from _pytest.tmpdir import TempPathFactory from _pytest.warning_types import PytestAssertRewriteWarning @@ -69,6 +70,7 @@ __all__ = [ "_fillfuncargs", "approx", "Cache", + "CallInfo", "CaptureFixture", "Class", "cmdline", |