Bug: QApplication() raise nothing on tty

John Ehresman jpe at wingware.com
Tue Jul 18 19:08:11 BST 2023


There are some things that PyQt can catch and defining sys.excepthook is what applications that want to do something with exceptions need to do. There are other things that PyQt cannot catch due to how Qt works — for those things, the Qt C++ code would need to change before PyQt could raise an exception.

John

> On Jul 18, 2023, at 1:24 PM, Raymond Osborn <rayosborn at mac.com> wrote:
> 
> Hi Florian,
> This is not really my area of expertise, even though I had to deal with this issue a few years ago. However, I would have thought that, rather than abort the process, PyQt could have raised a RuntimeError instead, with whatever traceback information is now provided as arguments to the sys.excepthook function. As Christian discovered, aborting the application makes diagnosing the problem extremely difficult.
> 
> Ray Osborn
> 
>> On Jul 18, 2023, at 4:57 AM, Florian Bruhin <me at the-compiler.org> wrote:
>> 
>> Hey,
>> 
>>> I presume this problem is the same as the one that caused NeXpy to
>>> start crashing starting with PyQt 5.5 (see
>>> https://github.com/nexpy/nexpy/commit/b19480a37e1d14278945672c08cab614a87b15eb).
>>> This seemed to be, in my opinion, an unfortunate design decision by Qt
>>> to abort a process whenever an error was encountered, in a way that
>>> was inaccessible to Python exception handling.
>> 
>> That's about what happens when there's an unhandled Python exception
>> from Python called from C++ code.
>> 
>> It won't change anything about what happens when Qt calls abort()
>> (via qFatal()).
>> 
>>> I think there could be an argument for PyQt providing a default way to
>>> catch these exceptions by defining its own sys.excepthook function,
>>> but it might be difficult to guarantee that such a function doesn’t
>>> interfere with other applications that define their own. Perhaps it
>>> could be an argument when generating the QApplication instance.
>> 
>> This behavior is coming from PyQt in the first place - it checks if a
>> sys.excepthook is defined, and if not, it aborts.
>> 
>> This is needed because, if Python is called from C++, and an exception
>> happens, there are only two ways for PyQt to get out of that situation:
>> 
>> 1) Print the exception to stdout, and return some kind of default value
>> to C++ (e.g. an empty string, or 0, or ...). This is what PyQt did
>> before 5.5, but it lead to people missing exceptions and all kinds of
>> funny undefined behavior (since PyQt basically just made up a value to
>> return).
>> 
>> 2) abort the process, which is what it does since 5.5.
>> 
>> Yes, 2) is somewhat annoying. But it's the safer choice as 1), which
>> basically amounts to "silently ignore all exceptions and do something
>> random instead". Thus you basically need to opt into it by setting a
>> sys.excepthook.
>> 
>> Florian



More information about the PyQt mailing list