[PyKDE] problem with exceptions within events

Ulrich Berning ulrich.berning at desys.de
Fri Feb 25 11:51:54 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.

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.


More information about the PyQt mailing list