Chain exceptions at C level, as already done at Python level.

Python 3 introduced a new killer feature: exceptions are chained by default, PEP 3134.

Example:

try: raise TypeError("err1") except TypeError: raise ValueError("err2")

Output:

Traceback (most recent call last): File "test.py", line 2, in <module> raise TypeError("err1") TypeError: err1 During handling of the above exception, another exception occurred: Traceback (most recent call last): File "test.py", line 4, in <module> raise ValueError("err2") ValueError: err2

Exceptions are chained by default in Python code, but not in extensions written in C.

A new private _PyErr_ChainExceptions() function was introduced in Python 3.4.3 and 3.5 to chain exceptions. Currently, it must be called explicitly to chain exceptions and its usage is not trivial.

Example of _PyErr_ChainExceptions() usage from the zipimport module to chain the previous OSError to a new ZipImportError exception:

PyObject *exc, *val, *tb; PyErr_Fetch(&exc, &val, &tb); PyErr_Format(ZipImportError, "can't open Zip file: %R", archive); _PyErr_ChainExceptions(exc, val, tb);

This PEP proposes to also chain exceptions automatically at C level to stay consistent and give more information on failures to help debugging. The previous example becomes simply:

PyErr_Format(ZipImportError, "can't open Zip file: %R", archive);