Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support PEP-415's Exception.__suppress_context__ #2631

Closed
2 tasks done
jmoldow opened this issue Jul 29, 2017 · 1 comment
Closed
2 tasks done

Support PEP-415's Exception.__suppress_context__ #2631

jmoldow opened this issue Jul 29, 2017 · 1 comment

Comments

@jmoldow
Copy link
Contributor

jmoldow commented Jul 29, 2017

  • Include a detailed description of the bug or suggestion

PEP-415 states that exception.__context__ should be suppressed in traceback outputs, if exception.__suppress_context__ is True.

If a raise exception from None is caught by pytest, pytest should not chain the context in the test report.

The current algorithm in _pytest._code.code.FormattedExcinfo is:

if e.__cause__ is not None:
    # Code to chain the cause.
elif e.__context__ is not None:
    # Code to chain the context.

which means that pytest always chains the exception, assuming that e.__context__ hasn't been set to None.

By comparison, the algorithm in traceback.TracebackException is:

if e.__cause__ is not None:
    # Code to chain the cause.
elif (e.__context__ is not None and not e.__suppress_context__):
    # Code to chain the context.

Exception.__suppress_context__ is available in all of the versions of Python 3 that are supported by pytest, so it is trivial to add support for this feature.

  • Minimal example if possible

Here's a test that has a raise exception from None in it:

def test_raise_from_none():
    try:
        raise ValueError()
    except Exception:
        raise AttributeError() from None

This is the test output (with the chained exception traceback) that results when running against the pytest feature branch (commit 768edde):

_____________________________________________________ test_raise_from_none _____________________________________________________

    def test_raise_from_none():
        try:
>           raise ValueError()
E           ValueError

testing/code/test_excinfo.py:1257: ValueError

During handling of the above exception, another exception occurred:

    def test_raise_from_none():
        try:
            raise ValueError()
        except Exception:
>           raise AttributeError() from None
E           AttributeError

testing/code/test_excinfo.py:1259: AttributeError

But running the same code in a terminal produces this shorter, non-chained traceback:

AttributeError                            Traceback (most recent call last)
<ipython-input-51-e2e3809c49fb> in <module>()
----> 1 test_raise_from_none()

<ipython-input-50-d651befdf00e> in test_raise_from_none()
      3         raise ValueError()
      4     except Exception:
----> 5         raise AttributeError() from None
      6

AttributeError:

And this is what the pytest output should look like:

_____________________________________________________ test_raise_from_none _____________________________________________________

    def test_raise_from_none():
        try:
            raise ValueError()
        except Exception:
>           raise AttributeError() from None
E           AttributeError

testing/code/test_excinfo.py:1259: AttributeError
jmoldow added a commit to jmoldow/pytest that referenced this issue Jul 29, 2017
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 pytest-dev#2631.
@nicoddemus
Copy link
Member

Fixed by #2632

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants