Type-annotate ExceptionInfo
This commit is contained in:
parent
2dca68b863
commit
55a570e513
|
@ -5,6 +5,11 @@ import traceback
|
||||||
from inspect import CO_VARARGS
|
from inspect import CO_VARARGS
|
||||||
from inspect import CO_VARKEYWORDS
|
from inspect import CO_VARKEYWORDS
|
||||||
from traceback import format_exception_only
|
from traceback import format_exception_only
|
||||||
|
from types import TracebackType
|
||||||
|
from typing import Optional
|
||||||
|
from typing import Pattern
|
||||||
|
from typing import Tuple
|
||||||
|
from typing import Union
|
||||||
from weakref import ref
|
from weakref import ref
|
||||||
|
|
||||||
import attr
|
import attr
|
||||||
|
@ -15,6 +20,9 @@ import _pytest
|
||||||
from _pytest._io.saferepr import safeformat
|
from _pytest._io.saferepr import safeformat
|
||||||
from _pytest._io.saferepr import saferepr
|
from _pytest._io.saferepr import saferepr
|
||||||
|
|
||||||
|
if False: # TYPE_CHECKING
|
||||||
|
from typing import Type
|
||||||
|
|
||||||
|
|
||||||
class Code:
|
class Code:
|
||||||
""" wrapper around Python code objects """
|
""" wrapper around Python code objects """
|
||||||
|
@ -379,12 +387,14 @@ class ExceptionInfo:
|
||||||
|
|
||||||
_assert_start_repr = "AssertionError('assert "
|
_assert_start_repr = "AssertionError('assert "
|
||||||
|
|
||||||
_excinfo = attr.ib()
|
_excinfo = attr.ib(
|
||||||
_striptext = attr.ib(default="")
|
type=Optional[Tuple["Type[BaseException]", BaseException, TracebackType]]
|
||||||
_traceback = attr.ib(default=None)
|
)
|
||||||
|
_striptext = attr.ib(type=str, default="")
|
||||||
|
_traceback = attr.ib(type=Optional[Traceback], default=None)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_current(cls, exprinfo=None):
|
def from_current(cls, exprinfo: Optional[str] = None) -> "ExceptionInfo":
|
||||||
"""returns an ExceptionInfo matching the current traceback
|
"""returns an ExceptionInfo matching the current traceback
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
@ -396,8 +406,11 @@ class ExceptionInfo:
|
||||||
strip ``AssertionError`` from the output, defaults
|
strip ``AssertionError`` from the output, defaults
|
||||||
to the exception message/``__str__()``
|
to the exception message/``__str__()``
|
||||||
"""
|
"""
|
||||||
tup = sys.exc_info()
|
tup_ = sys.exc_info()
|
||||||
assert tup[0] is not None, "no current exception"
|
assert tup_[0] is not None, "no current exception"
|
||||||
|
assert tup_[1] is not None, "no current exception"
|
||||||
|
assert tup_[2] is not None, "no current exception"
|
||||||
|
tup = (tup_[0], tup_[1], tup_[2])
|
||||||
_striptext = ""
|
_striptext = ""
|
||||||
if exprinfo is None and isinstance(tup[1], AssertionError):
|
if exprinfo is None and isinstance(tup[1], AssertionError):
|
||||||
exprinfo = getattr(tup[1], "msg", None)
|
exprinfo = getattr(tup[1], "msg", None)
|
||||||
|
@ -409,48 +422,60 @@ class ExceptionInfo:
|
||||||
return cls(tup, _striptext)
|
return cls(tup, _striptext)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def for_later(cls):
|
def for_later(cls) -> "ExceptionInfo":
|
||||||
"""return an unfilled ExceptionInfo
|
"""return an unfilled ExceptionInfo
|
||||||
"""
|
"""
|
||||||
return cls(None)
|
return cls(None)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def type(self):
|
def type(self) -> "Type[BaseException]":
|
||||||
"""the exception class"""
|
"""the exception class"""
|
||||||
|
assert (
|
||||||
|
self._excinfo is not None
|
||||||
|
), ".type can only be used after the context manager exits"
|
||||||
return self._excinfo[0]
|
return self._excinfo[0]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def value(self):
|
def value(self) -> BaseException:
|
||||||
"""the exception value"""
|
"""the exception value"""
|
||||||
|
assert (
|
||||||
|
self._excinfo is not None
|
||||||
|
), ".value can only be used after the context manager exits"
|
||||||
return self._excinfo[1]
|
return self._excinfo[1]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tb(self):
|
def tb(self) -> TracebackType:
|
||||||
"""the exception raw traceback"""
|
"""the exception raw traceback"""
|
||||||
|
assert (
|
||||||
|
self._excinfo is not None
|
||||||
|
), ".tb can only be used after the context manager exits"
|
||||||
return self._excinfo[2]
|
return self._excinfo[2]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def typename(self):
|
def typename(self) -> str:
|
||||||
"""the type name of the exception"""
|
"""the type name of the exception"""
|
||||||
|
assert (
|
||||||
|
self._excinfo is not None
|
||||||
|
), ".typename can only be used after the context manager exits"
|
||||||
return self.type.__name__
|
return self.type.__name__
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def traceback(self):
|
def traceback(self) -> Traceback:
|
||||||
"""the traceback"""
|
"""the traceback"""
|
||||||
if self._traceback is None:
|
if self._traceback is None:
|
||||||
self._traceback = Traceback(self.tb, excinfo=ref(self))
|
self._traceback = Traceback(self.tb, excinfo=ref(self))
|
||||||
return self._traceback
|
return self._traceback
|
||||||
|
|
||||||
@traceback.setter
|
@traceback.setter
|
||||||
def traceback(self, value):
|
def traceback(self, value: Traceback) -> None:
|
||||||
self._traceback = value
|
self._traceback = value
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self) -> str:
|
||||||
if self._excinfo is None:
|
if self._excinfo is None:
|
||||||
return "<ExceptionInfo for raises contextmanager>"
|
return "<ExceptionInfo for raises contextmanager>"
|
||||||
return "<ExceptionInfo %s tblen=%d>" % (self.typename, len(self.traceback))
|
return "<ExceptionInfo %s tblen=%d>" % (self.typename, len(self.traceback))
|
||||||
|
|
||||||
def exconly(self, tryshort=False):
|
def exconly(self, tryshort: bool = False) -> str:
|
||||||
""" return the exception as a string
|
""" return the exception as a string
|
||||||
|
|
||||||
when 'tryshort' resolves to True, and the exception is a
|
when 'tryshort' resolves to True, and the exception is a
|
||||||
|
@ -466,11 +491,11 @@ class ExceptionInfo:
|
||||||
text = text[len(self._striptext) :]
|
text = text[len(self._striptext) :]
|
||||||
return text
|
return text
|
||||||
|
|
||||||
def errisinstance(self, exc):
|
def errisinstance(self, exc: "Type[BaseException]") -> bool:
|
||||||
""" return True if the exception is an instance of exc """
|
""" return True if the exception is an instance of exc """
|
||||||
return isinstance(self.value, exc)
|
return isinstance(self.value, exc)
|
||||||
|
|
||||||
def _getreprcrash(self):
|
def _getreprcrash(self) -> "ReprFileLocation":
|
||||||
exconly = self.exconly(tryshort=True)
|
exconly = self.exconly(tryshort=True)
|
||||||
entry = self.traceback.getcrashentry()
|
entry = self.traceback.getcrashentry()
|
||||||
path, lineno = entry.frame.code.raw.co_filename, entry.lineno
|
path, lineno = entry.frame.code.raw.co_filename, entry.lineno
|
||||||
|
@ -478,13 +503,13 @@ class ExceptionInfo:
|
||||||
|
|
||||||
def getrepr(
|
def getrepr(
|
||||||
self,
|
self,
|
||||||
showlocals=False,
|
showlocals: bool = False,
|
||||||
style="long",
|
style: str = "long",
|
||||||
abspath=False,
|
abspath: bool = False,
|
||||||
tbfilter=True,
|
tbfilter: bool = True,
|
||||||
funcargs=False,
|
funcargs: bool = False,
|
||||||
truncate_locals=True,
|
truncate_locals: bool = True,
|
||||||
chain=True,
|
chain: bool = True,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Return str()able representation of this exception info.
|
Return str()able representation of this exception info.
|
||||||
|
@ -535,7 +560,7 @@ class ExceptionInfo:
|
||||||
)
|
)
|
||||||
return fmt.repr_excinfo(self)
|
return fmt.repr_excinfo(self)
|
||||||
|
|
||||||
def match(self, regexp):
|
def match(self, regexp: Union[str, Pattern]) -> bool:
|
||||||
"""
|
"""
|
||||||
Check whether the regular expression 'regexp' is found in the string
|
Check whether the regular expression 'regexp' is found in the string
|
||||||
representation of the exception using ``re.search``. If it matches
|
representation of the exception using ``re.search``. If it matches
|
||||||
|
|
Loading…
Reference in New Issue