summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRan Benita <ran@unusedvar.com>2020-12-26 21:23:23 +0200
committerRan Benita <ran@unusedvar.com>2020-12-26 21:38:37 +0200
commit96ea867fec556a8d0e2b60392927572da38c88df (patch)
treeb707a925e9f7655ae157da7927df80c4855d8e62 /src
parentbd76042344b3c3318dddf991c08d49bbce2251bb (diff)
downloadpytest-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.py73
-rw-r--r--src/pytest/__init__.py2
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",