This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author vstinner
Recipients vstinner
Date 2015-03-24.14:41:37
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1427208097.93.0.892198283241.issue23763@psf.upfronthosting.co.za>
In-reply-to
Content
In Python 3, it becomes possible to chain two exceptions. It's one of the killer feature of Python 3, it helps debugging.


In Python, exceptions are chained by default. Example:

    try:
        raise TypeError("old message")
    except TypeError:
        raise ValueError("new message")

Output:

    Traceback (most recent call last):
      File "x.py", line 2, in <module>
        raise TypeError("old message")
    TypeError: old message

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "x.py", line 4, in <module>
        raise ValueError("new message")
    ValueError: new message

In C, using the public PyErr_SetNone(), PyErr_Format(), PyErr_SetString(), ... functions, exceptions are *not* chained by default.

You have to call explicitly the new private _PyErr_ChainExceptions() function introduced in Python 3.4. It is not trivial to use it: you have to call PyErr_Fetch() and check if an exception was already raised.


In Python, the following examples are bad practice because they may hide important exceptions like MemoryError or KeyboardInterrupt:

    try:
        ....
    except:
        pass

or

    try:
        ....
    except:
        raise ValueError(...)

In C extensions, it's common to write such code, few functions check which exception was raised.


Last months, I enhanced Python to detect exceptions ignored by mistake: I added assert(!PyErr_Occurred()) in many functions which can clear the current exception (ex: call PyErr_Clear()) or raise a new exception (ex: call PyErr_SetString(...)). The last step is the issue #23571 which now implements in release mode.


For the next step, I propose to explicitly clear the current exception before raising a new exception.


I don't know yet if it would be a good idea to modify PyErr_*() functions to automatically chain exceptions.
History
Date User Action Args
2015-03-24 14:41:37vstinnersetrecipients: + vstinner
2015-03-24 14:41:37vstinnersetmessageid: <1427208097.93.0.892198283241.issue23763@psf.upfronthosting.co.za>
2015-03-24 14:41:37vstinnerlinkissue23763 messages
2015-03-24 14:41:37vstinnercreate