Support PEP-415's Exception.__suppress_context__
PEP-415 states that `exception.__context__` should be suppressed in traceback outputs, if `exception.__suppress_context__` is `True`. Now if a ``raise exception from None`` is caught by pytest, pytest will no longer chain the context in the test report. The algorithm in `FormattedExcinfo` now better matches the one in `traceback.TracebackException`. `Exception.__suppress_context__` is available in all of the versions of Python 3 that are supported by pytest. Fixes #2631.
This commit is contained in:
parent
768edde899
commit
2e61f702c0
1
AUTHORS
1
AUTHORS
|
@ -84,6 +84,7 @@ John Towler
|
|||
Jon Sonesen
|
||||
Jonas Obrist
|
||||
Jordan Guymon
|
||||
Jordan Moldow
|
||||
Joshua Bronson
|
||||
Jurko Gospodnetić
|
||||
Justyna Janczyszyn
|
||||
|
|
|
@ -679,7 +679,7 @@ class FormattedExcinfo(object):
|
|||
e = e.__cause__
|
||||
excinfo = ExceptionInfo((type(e), e, e.__traceback__)) if e.__traceback__ else None
|
||||
descr = 'The above exception was the direct cause of the following exception:'
|
||||
elif e.__context__ is not None:
|
||||
elif (e.__context__ is not None and not e.__suppress_context__):
|
||||
e = e.__context__
|
||||
excinfo = ExceptionInfo((type(e), e, e.__traceback__)) if e.__traceback__ else None
|
||||
descr = 'During handling of the above exception, another exception occurred:'
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Added support for `PEP-415's <https://www.python.org/dev/peps/pep-0415/>`_
|
||||
``Exception.__suppress_context__``. Now if a ``raise exception from None`` is
|
||||
caught by pytest, pytest will no longer chain the context in the test report.
|
||||
The behavior now matches Python's traceback behavior.
|
|
@ -1095,6 +1095,36 @@ raise ValueError()
|
|||
assert line.endswith('mod.py')
|
||||
assert tw.lines[47] == ":15: AttributeError"
|
||||
|
||||
@pytest.mark.skipif("sys.version_info[0] < 3")
|
||||
def test_exc_repr_with_raise_from_none_chain_suppression(self, importasmod):
|
||||
mod = importasmod("""
|
||||
def f():
|
||||
try:
|
||||
g()
|
||||
except Exception:
|
||||
raise AttributeError() from None
|
||||
def g():
|
||||
raise ValueError()
|
||||
""")
|
||||
excinfo = pytest.raises(AttributeError, mod.f)
|
||||
r = excinfo.getrepr(style="long")
|
||||
tw = TWMock()
|
||||
r.toterminal(tw)
|
||||
for line in tw.lines:
|
||||
print(line)
|
||||
assert tw.lines[0] == ""
|
||||
assert tw.lines[1] == " def f():"
|
||||
assert tw.lines[2] == " try:"
|
||||
assert tw.lines[3] == " g()"
|
||||
assert tw.lines[4] == " except Exception:"
|
||||
assert tw.lines[5] == "> raise AttributeError() from None"
|
||||
assert tw.lines[6] == "E AttributeError"
|
||||
assert tw.lines[7] == ""
|
||||
line = tw.get_write_msg(8)
|
||||
assert line.endswith('mod.py')
|
||||
assert tw.lines[9] == ":6: AttributeError"
|
||||
assert len(tw.lines) == 10
|
||||
|
||||
@pytest.mark.skipif("sys.version_info[0] < 3")
|
||||
@pytest.mark.parametrize('reason, description', [
|
||||
('cause', 'The above exception was the direct cause of the following exception:'),
|
||||
|
|
Loading…
Reference in New Issue