code: export ExceptionInfo for typing purposes
This type is most prominent in `pytest.raises` and we should allow to refer to it by a public name. The type is not in a perfectly "exposable" state. In particular: - The `traceback` property with type `Traceback` which is derived from the `py.code` API and exposes a bunch more types transitively. This stuff is *not* exported and probably won't be. - The `getrepr` method which probably should be private. But they're already used in the wild so no point in just hiding them now. The __init__ API is hidden -- the public API for this are the `from_*` classmethods.
This commit is contained in:
@@ -42,6 +42,7 @@ from _pytest._io.saferepr import safeformat
|
||||
from _pytest._io.saferepr import saferepr
|
||||
from _pytest.compat import final
|
||||
from _pytest.compat import get_real_func
|
||||
from _pytest.deprecated import check_ispytest
|
||||
from _pytest.pathlib import absolutepath
|
||||
from _pytest.pathlib import bestrelpath
|
||||
|
||||
@@ -440,15 +441,28 @@ E = TypeVar("E", bound=BaseException, covariant=True)
|
||||
|
||||
|
||||
@final
|
||||
@attr.s(repr=False)
|
||||
@attr.s(repr=False, init=False)
|
||||
class ExceptionInfo(Generic[E]):
|
||||
"""Wraps sys.exc_info() objects and offers help for navigating the traceback."""
|
||||
|
||||
_assert_start_repr = "AssertionError('assert "
|
||||
|
||||
_excinfo = attr.ib(type=Optional[Tuple[Type["E"], "E", TracebackType]])
|
||||
_striptext = attr.ib(type=str, default="")
|
||||
_traceback = attr.ib(type=Optional[Traceback], default=None)
|
||||
_striptext = attr.ib(type=str)
|
||||
_traceback = attr.ib(type=Optional[Traceback])
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
excinfo: Optional[Tuple[Type["E"], "E", TracebackType]],
|
||||
striptext: str = "",
|
||||
traceback: Optional[Traceback] = None,
|
||||
*,
|
||||
_ispytest: bool = False,
|
||||
) -> None:
|
||||
check_ispytest(_ispytest)
|
||||
self._excinfo = excinfo
|
||||
self._striptext = striptext
|
||||
self._traceback = traceback
|
||||
|
||||
@classmethod
|
||||
def from_exc_info(
|
||||
@@ -475,7 +489,7 @@ class ExceptionInfo(Generic[E]):
|
||||
if exprinfo and exprinfo.startswith(cls._assert_start_repr):
|
||||
_striptext = "AssertionError: "
|
||||
|
||||
return cls(exc_info, _striptext)
|
||||
return cls(exc_info, _striptext, _ispytest=True)
|
||||
|
||||
@classmethod
|
||||
def from_current(
|
||||
@@ -502,7 +516,7 @@ class ExceptionInfo(Generic[E]):
|
||||
@classmethod
|
||||
def for_later(cls) -> "ExceptionInfo[E]":
|
||||
"""Return an unfilled ExceptionInfo."""
|
||||
return cls(None)
|
||||
return cls(None, _ispytest=True)
|
||||
|
||||
def fill_unfilled(self, exc_info: Tuple[Type[E], E, TracebackType]) -> None:
|
||||
"""Fill an unfilled ExceptionInfo created with ``for_later()``."""
|
||||
@@ -922,7 +936,7 @@ class FormattedExcinfo:
|
||||
if e.__cause__ is not None and self.chain:
|
||||
e = e.__cause__
|
||||
excinfo_ = (
|
||||
ExceptionInfo((type(e), e, e.__traceback__))
|
||||
ExceptionInfo.from_exc_info((type(e), e, e.__traceback__))
|
||||
if e.__traceback__
|
||||
else None
|
||||
)
|
||||
@@ -932,7 +946,7 @@ class FormattedExcinfo:
|
||||
):
|
||||
e = e.__context__
|
||||
excinfo_ = (
|
||||
ExceptionInfo((type(e), e, e.__traceback__))
|
||||
ExceptionInfo.from_exc_info((type(e), e, e.__traceback__))
|
||||
if e.__traceback__
|
||||
else None
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user