mirror of
https://github.com/python/cpython.git
synced 2025-09-27 10:50:04 +00:00
Close #20105: set __traceback__ when chaining exceptions in C
This commit is contained in:
parent
23e37aa7b7
commit
77b286b2cc
5 changed files with 27 additions and 2 deletions
|
@ -90,6 +90,16 @@ in various ways. There is a separate error indicator for each thread.
|
||||||
the class in that case. If the values are already normalized, nothing happens.
|
the class in that case. If the values are already normalized, nothing happens.
|
||||||
The delayed normalization is implemented to improve performance.
|
The delayed normalization is implemented to improve performance.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
This function *does not* implicitly set the ``__traceback__``
|
||||||
|
attribute on the exception value. If setting the traceback
|
||||||
|
appropriately is desired, the following additional snippet is needed::
|
||||||
|
|
||||||
|
if (tb != NULL) {
|
||||||
|
PyException_SetTraceback(val, tb);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: void PyErr_Clear()
|
.. c:function:: void PyErr_Clear()
|
||||||
|
|
||||||
|
|
|
@ -264,6 +264,9 @@ name of the codec responsible for producing the error::
|
||||||
>>> import codecs
|
>>> import codecs
|
||||||
|
|
||||||
>>> codecs.decode(b"abcdefgh", "hex")
|
>>> codecs.decode(b"abcdefgh", "hex")
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "/usr/lib/python3.4/encodings/hex_codec.py", line 20, in hex_decode
|
||||||
|
return (binascii.a2b_hex(input), len(input))
|
||||||
binascii.Error: Non-hexadecimal digit found
|
binascii.Error: Non-hexadecimal digit found
|
||||||
|
|
||||||
The above exception was the direct cause of the following exception:
|
The above exception was the direct cause of the following exception:
|
||||||
|
@ -273,6 +276,11 @@ name of the codec responsible for producing the error::
|
||||||
binascii.Error: decoding with 'hex' codec failed (Error: Non-hexadecimal digit found)
|
binascii.Error: decoding with 'hex' codec failed (Error: Non-hexadecimal digit found)
|
||||||
|
|
||||||
>>> codecs.encode("hello", "bz2")
|
>>> codecs.encode("hello", "bz2")
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "/usr/lib/python3.4/encodings/bz2_codec.py", line 17, in bz2_encode
|
||||||
|
return (bz2.compress(input), len(input))
|
||||||
|
File "/usr/lib/python3.4/bz2.py", line 498, in compress
|
||||||
|
return comp.compress(data) + comp.flush()
|
||||||
TypeError: 'str' does not support the buffer interface
|
TypeError: 'str' does not support the buffer interface
|
||||||
|
|
||||||
The above exception was the direct cause of the following exception:
|
The above exception was the direct cause of the following exception:
|
||||||
|
|
|
@ -2522,6 +2522,7 @@ class ExceptionChainingTest(unittest.TestCase):
|
||||||
with self.assertRaisesRegex(exc_type, full_msg) as caught:
|
with self.assertRaisesRegex(exc_type, full_msg) as caught:
|
||||||
yield caught
|
yield caught
|
||||||
self.assertIsInstance(caught.exception.__cause__, exc_type)
|
self.assertIsInstance(caught.exception.__cause__, exc_type)
|
||||||
|
self.assertIsNotNone(caught.exception.__cause__.__traceback__)
|
||||||
|
|
||||||
def raise_obj(self, *args, **kwds):
|
def raise_obj(self, *args, **kwds):
|
||||||
# Helper to dynamically change the object raised by a test codec
|
# Helper to dynamically change the object raised by a test codec
|
||||||
|
|
|
@ -36,6 +36,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #20105: the codec exception chaining now correctly sets the
|
||||||
|
traceback of the original exception as its __traceback__ attribute.
|
||||||
|
|
||||||
- asyncio: Various improvements and small changes not all covered by
|
- asyncio: Various improvements and small changes not all covered by
|
||||||
issues listed below. E.g. wait_for() now cancels the inner task if
|
issues listed below. E.g. wait_for() now cancels the inner task if
|
||||||
the timeout occcurs; tweaked the set of exported symbols; renamed
|
the timeout occcurs; tweaked the set of exported symbols; renamed
|
||||||
|
|
|
@ -2689,8 +2689,11 @@ _PyErr_TrySetFromCause(const char *format, ...)
|
||||||
* types as well, but that's quite a bit trickier due to the extra
|
* types as well, but that's quite a bit trickier due to the extra
|
||||||
* state potentially stored on OSError instances.
|
* state potentially stored on OSError instances.
|
||||||
*/
|
*/
|
||||||
|
/* Ensure the traceback is set correctly on the existing exception */
|
||||||
Py_XDECREF(tb);
|
if (tb != NULL) {
|
||||||
|
PyException_SetTraceback(val, tb);
|
||||||
|
Py_DECREF(tb);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_STDARG_PROTOTYPES
|
#ifdef HAVE_STDARG_PROTOTYPES
|
||||||
va_start(vargs, format);
|
va_start(vargs, format);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue