[Pyrex] Exception stomping

Eric Huss e-huss at netmeridian.com
Wed Nov 26 01:27:25 CET 2008


I've run into a problem with how Pyrex handles the "current" exception
(not sure if this has been discussed before).  I know that the "reraise"
issue has been fixed, but this is a slightly different issue where Pyrex
does not make a backup of the "current" exception.

If you call a Pyrex function that internally raises and catches an
exception, but does not re-raise it, it leaves that exception set within
the tstate object.  This causes the exception to bleed out in unexpected
ways.

Attached is an example that illustrates the problem.

In the Python interpreter, when you leave a frame, it typically restores
tstate->exc_* (via the reset_exc_info function) to whatever it used to be
(the backup kept inside the frame object).  Pyrex does not make a backup,
and inside __Pyx_GetException it stomps on tstate->exc_*.

Perhaps a solution would be to emulate what set_exc_info/reset_exc_info do
inside the interpreter using local variables stored on the C stack,
similar to how the "reraise" fix was implemented.

My only thought on a workaround at the moment is to somehow manually
backup tstate->exc_* in any Pyrex function that has an exception handler
that does not reraise.  However, that is pretty messy and prone to subtle
bugs and refcount issues, so I'm a little reluctant to head that way.

-Eric
-------------- next part --------------
import test_exc

def foo():
    try:
        raise ValueError(3)
    except ValueError:
        raise


def test():
    try:
        foo()
    except:
        test_exc.bar()
        # Re-raise foo exception which should be ValueError(3)
        raise

if __name__ == '__main__':
    test()
-------------- next part --------------
def bar():
    try:
        raise ValueError(4)
    except ValueError:
        pass


More information about the Pyrex mailing list