I retract what I said above. PyErr_SetObject() and friends only change
tstate->curexc_* variables, not tstate->exc_*.
The former (tstate->curexc_*) contain the current, pending (uncaught)
exception state of the thread. The latter (tstate->exc_*) contain the
exception currently handled by an "except" statement in Python code.
So, theoretically, there is no way calling PyEval_CallObject() can
change tstate->exc_value:
- if it raises an exception or calls code that raises an exception
without catching it, the exception ends up in tstate->curexc_*, not in
tstate->exc_*
- if it calls code that raises an exception /and catches it/, exception
stacking means the exception should be discarded after the end of the
"except" block and the last tstate->exc_* values restored.
Of course, there may be bugs in the implementation of the above. The
best way to find out would be to have a small snippet of Python code
reproducing the problem. :-) |