Phil Thompson schrieb:

Hello,

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.

Ulli





_______________________________________________
PyKDE mailing list    PyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde

Reply via email to