Fixed #25761 -- Added __cause__.__traceback__ to reraised exceptions.

When Django reraises an exception, it sets the __cause__ attribute even
in Python 2, mimicking Python's 3 behavior for "raise Foo from Bar".
However, Python 3 also ensures that all exceptions have a __traceback__
attribute and thus the "traceback2" Python 2 module (backport of Python
3's "traceback" module) relies on the fact that whenever you have a
__cause__ attribute, the recorded exception also has a __traceback__
attribute.

This is breaking testtools which is using traceback2 (see
https://github.com/testing-cabal/testtools/issues/162).

This commit fixes this inconsistency by ensuring that Django sets
the __traceback__ attribute on any exception stored in a __cause__
attribute of a reraised exception.
This commit is contained in:
Raphaël Hertzog 2015-11-25 12:54:52 +01:00 committed by Tim Graham
parent c6ea4ed5d2
commit 9f4e031bd3
4 changed files with 13 additions and 1 deletions

View file

@ -196,7 +196,13 @@ As per :pep:`3134`, a ``__cause__`` attribute is set with the original
(underlying) database exception, allowing access to any additional
information provided. (Note that this attribute is available under
both Python 2 and Python 3, although :pep:`3134` normally only applies
to Python 3.)
to Python 3. To avoid unexpected differences with Python 3, Django will also
ensure that the exception made available via ``__cause__`` has a usable
``__traceback__`` attribute.)
.. versionchanged:: 1.10
The ``__traceback__`` attribute described above was added.
.. exception:: models.ProtectedError