code: make TracebackEntry immutable
TracebackEntry being mutable caught me by surprise and makes reasoning about the exception formatting code harder. Make it a proper value.
This commit is contained in:
parent
0a20452f78
commit
6f7f89f3c4
|
@ -49,6 +49,7 @@ from _pytest.pathlib import absolutepath
|
|||
from _pytest.pathlib import bestrelpath
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing_extensions import Final
|
||||
from typing_extensions import Literal
|
||||
from typing_extensions import SupportsIndex
|
||||
|
||||
|
@ -197,18 +198,20 @@ class TracebackEntry:
|
|||
def __init__(
|
||||
self,
|
||||
rawentry: TracebackType,
|
||||
repr_style: Optional['Literal["short", "long"]'] = None,
|
||||
) -> None:
|
||||
self._rawentry = rawentry
|
||||
self._repr_style: Optional['Literal["short", "long"]'] = None
|
||||
self._rawentry: "Final" = rawentry
|
||||
self._repr_style: "Final" = repr_style
|
||||
|
||||
def with_repr_style(
|
||||
self, repr_style: Optional['Literal["short", "long"]']
|
||||
) -> "TracebackEntry":
|
||||
return TracebackEntry(self._rawentry, repr_style)
|
||||
|
||||
@property
|
||||
def lineno(self) -> int:
|
||||
return self._rawentry.tb_lineno - 1
|
||||
|
||||
def set_repr_style(self, mode: "Literal['short', 'long']") -> None:
|
||||
assert mode in ("short", "long")
|
||||
self._repr_style = mode
|
||||
|
||||
@property
|
||||
def frame(self) -> Frame:
|
||||
return Frame(self._rawentry.tb_frame)
|
||||
|
|
|
@ -35,6 +35,7 @@ from _pytest._code import filter_traceback
|
|||
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._io import TerminalWriter
|
||||
from _pytest._io.saferepr import saferepr
|
||||
from _pytest.compat import ascii_escaped
|
||||
|
@ -1819,8 +1820,12 @@ class Function(PyobjMixin, nodes.Item):
|
|||
# only show a single-line message for each frame.
|
||||
if self.config.getoption("tbstyle", "auto") == "auto":
|
||||
if len(excinfo.traceback) > 2:
|
||||
for entry in excinfo.traceback[1:-1]:
|
||||
entry.set_repr_style("short")
|
||||
excinfo.traceback = Traceback(
|
||||
entry
|
||||
if i == 0 or i == len(excinfo.traceback) - 1
|
||||
else entry.with_repr_style("short")
|
||||
for i, entry in enumerate(excinfo.traceback)
|
||||
)
|
||||
|
||||
# TODO: Type ignored -- breaks Liskov Substitution.
|
||||
def repr_failure( # type: ignore[override]
|
||||
|
|
|
@ -1122,8 +1122,10 @@ raise ValueError()
|
|||
)
|
||||
excinfo = pytest.raises(ValueError, mod.f)
|
||||
excinfo.traceback = excinfo.traceback.filter(excinfo)
|
||||
excinfo.traceback[1].set_repr_style("short")
|
||||
excinfo.traceback[2].set_repr_style("short")
|
||||
excinfo.traceback = _pytest._code.Traceback(
|
||||
entry if i not in (1, 2) else entry.with_repr_style("short")
|
||||
for i, entry in enumerate(excinfo.traceback)
|
||||
)
|
||||
r = excinfo.getrepr(style="long")
|
||||
r.toterminal(tw_mock)
|
||||
for line in tw_mock.lines:
|
||||
|
|
Loading…
Reference in New Issue