In PyQt4 and old versions of PyQt5 (5.4 or older) the behaviour was to never exit the application in any of the situations you describe. This was changed in PyQt 5.5+ (to cause the application to exit) but only if there is no exception handler explicitly specified for sys.excepthook
. This is somewhat mentioned in the documentation but also in more detail on the mailing list.
The relevant part from the documentation:
There are a number of situations where Python code is executed from
C++. Python reimplementations of C++ virtual methods is probably the
most common example. In previous versions, if the Python code raised
an exception then PyQt would call Python’s PyErr_Print() function
which would then call sys.excepthook(). The default exception hook
would then display the exception and any traceback to stderr. There
are number of disadvantages to this behaviour:
- the application does not terminate, meaning the behaviour is different
to when exceptions are raised in other situations
- the output written to stderr may not be seen by the developer or user (particularly if it
is a GUI application) thereby hiding the fact that the application is
trying to report a potential bug.
This behaviour was deprecated in
PyQt v5.4. In PyQt v5.5 an unhandled Python exception will result in a
call to Qt’s qFatal() function. By default this will call abort() and
the application will terminate. Note that an application installed
exception hook will still take precedence.
The relavant part from the mailing list thread:
I have just discovered the change to PyQt 5.5 in which unhandled exceptions
result in a call to qFatal(). Perhaps I am missing something important, but
I am a confused about why this behavior was chosen. The documentation
states that the problem with the old behavior is that "the application does
not terminate, meaning the behaviour is different to when exceptions are
raised in other situations". I have two concerns about this reasoning:
Because you can't cleanly exit Python when you're currently running
C++ code.
- Unhandled exceptions in Python do not cause the program to terminate;
they only cause sys.excepthook to be invoked.
Same with PyQt, if you set one.
It is perhaps also worth pointing out that the original question was raised on the pyqt mailing list by the creator of pyqtgraph and that staff at riverbank computing have said this new behaviour is not going away.
If you want to go to the source code, the relevant code is located in pyqt5/qpy/QtCore/qpycore_public_api.cpp (a forked version of PyQt5 is here)