Skip to content

Commit

Permalink
Merge pull request #3805 from asottile/cause_cycles
Browse files Browse the repository at this point in the history
Fix traceback reporting for exceptions with `__cause__` cycles.
  • Loading branch information
RonnyPfannschmidt committed Aug 16, 2018
2 parents 939a792 + 17644ff commit 7d4c4c6
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 1 deletion.
1 change: 1 addition & 0 deletions changelog/3804.bugfix.rst
@@ -0,0 +1 @@
Fix traceback reporting for exceptions with ``__cause__`` cycles.
4 changes: 3 additions & 1 deletion src/_pytest/_code/code.py
Expand Up @@ -719,7 +719,9 @@ def repr_excinfo(self, excinfo):
repr_chain = []
e = excinfo.value
descr = None
while e is not None:
seen = set()
while e is not None and id(e) not in seen:
seen.add(id(e))
if excinfo:
reprtraceback = self.repr_traceback(excinfo)
reprcrash = excinfo._getreprcrash()
Expand Down
45 changes: 45 additions & 0 deletions testing/code/test_excinfo.py
Expand Up @@ -4,6 +4,7 @@
import operator
import os
import sys
import textwrap
import _pytest
import py
import pytest
Expand Down Expand Up @@ -1265,6 +1266,50 @@ def g():
]
)

@pytest.mark.skipif("sys.version_info[0] < 3")
def test_exc_chain_repr_cycle(self, importasmod):
mod = importasmod(
"""
class Err(Exception):
pass
def fail():
return 0 / 0
def reraise():
try:
fail()
except ZeroDivisionError as e:
raise Err() from e
def unreraise():
try:
reraise()
except Err as e:
raise e.__cause__
"""
)
excinfo = pytest.raises(ZeroDivisionError, mod.unreraise)
r = excinfo.getrepr(style="short")
tw = TWMock()
r.toterminal(tw)
out = "\n".join(line for line in tw.lines if isinstance(line, str))
expected_out = textwrap.dedent(
"""\
:13: in unreraise
reraise()
:10: in reraise
raise Err() from e
E test_exc_chain_repr_cycle0.mod.Err
During handling of the above exception, another exception occurred:
:15: in unreraise
raise e.__cause__
:8: in reraise
fail()
:5: in fail
return 0 / 0
E ZeroDivisionError: division by zero"""
)
assert out == expected_out


@pytest.mark.parametrize("style", ["short", "long"])
@pytest.mark.parametrize("encoding", [None, "utf8", "utf16"])
Expand Down

0 comments on commit 7d4c4c6

Please sign in to comment.