[PyKDE] problem with exceptions within events

Phil Thompson phil at riverbankcomputing.co.uk
Fri Feb 25 12:08:45 GMT 2005

> Phil Thompson schrieb:
>>>it seems that Python exceptions generated within event handlers do not
>>> get
>>>propagated correctly. We use a sys.excepthook to abort gracefully with a
>>>messagebox from our application, and this seems to work in most cases
>>> but
>>>not within event handlers. For instance:
>>The old (ie. pre-SIP 4.2) behaviour was to call PyErr_Print() if an
>>exception was raised in a Python re-implementation of a C++ virtual
>>method. I never really liked this as it meant that the exception couldn't
>>be caught with try/except.
>>In SIP 4.2 I removed the calls to PyErr_Print() and added a check for a
>>Python exception after each called to a C++ method. The theory being that
>>a try/except around the corresponding Python method call would catch any
>>exception raised. There turned out to be two problems with this...
>>- The implementation was buggy. The SIP module was using exceptions in
>> the
>>meantime - it should have been saving and restoring any existing
>>exception. With this fixed exceptions are caught properly.
>>- It only works if the C++ method returns to allow the test for the
>>exception to be made. The one place where this doesn't happen is
>>QApplication.exec_loop(). Therefore you still have to rely on providing
>>your own sys.excepthook. However, it turns out that the excepthook is
>> only
>>called from within PyErr_Print().
>>So, rather than try and deal with the two conflicting requirements (being
>>able to catch as many exceptions as possible, and being able to detect
>>exceptions in exec_loop()) I plan to simply revert to the pre-SIP 4.2
>>behaviour - unless anybody has any other bright ideas.
> To recapitulate:
> 1.) If a Python method, called asynchronous by QApplication.exec_loop()
> raises an exception, the surrounding C++ method checks this and has to
> use PyErr_Print() to trigger the excepthook (either the default or your
> own excepthook).
> 2.) If a Python method, called synchronous, raises an exceptions, the
> surrounding C++ method checks this and let the calling Python code
> handle this exception.

That's a nice summary.

> Why not inspect the calling frames? A method called asynchronous by
> QApplication.exec_loop() must have exec_loop() in one of it's outer
> frames, a method called synchronous outside the exec_loop doesn't have
> exec_loop() in its outer frames. It's just an idea, don't know if it
> could work.

My first reaction is that it is very PyQt specific - you'd want to have an
annotation that allowed to you to mark a method as needing that sort of
treatment. I haven't done much with inspecting Python byte code, but the
phrase "can of worms" springs to mind.


More information about the PyQt mailing list