PyErr_Print vs PyErr_Display vs PyErr_WriteUnraisable (original) (raw)

January 31, 2025, 12:24pm 1

There are three ways to handle an exception if it cannot be passed to the caller in the C code:

Unfortunately, using these functions is not consistent across the extension code. I believe that PyErr_Print() is completely unappropriate in the library code due to its side effects – possibility to exit the program and asynchronous changing the sys attributes. It only should be used in the REPL and at the highest level of some programs. There may be some use for PyErr_Display(), but it is not so handy and flexible. You need to explicitly write the context of the error to the stderr before writing the exception, and there is no way to catch the output except substitude the stderr.

PyErr_FormatUnraisable() looks the most appropriate tool. It lacks traceback and other details, but importing from the traceback module may be unappropriate – the import machinery may not work at that stage (too early or too late).

colesbury (Sam Gross) February 11, 2025, 7:38pm 2

I started looking at this in the context of ctrl-c and KeyboardInterrupt. One problem with PyErr_WriteUnraisable is that it swallows KeyboardInterrupt and SystemError. It’s a bad user experience if ctrl-c doesn’t exit your program, just because the program happened to be running the GC, a finalizer, or any of the other 100+ places we write unraisable exceptions.