Hi,

I fixed most of the Py3 problems in the test suite. The last one relates to
exception chaining.

http://www.python.org/dev/peps/pep-3134/

Currently, when you write this:

    try: ...
    except SomeException:
        raise NewException

SomeException will remain in sys.exc_info(), or rather in
PyThreadState->exc_type/value/tb. Subsequently raised exceptions will find
it there and make it their "context". A way to fix this is to put this into
Pyx_ErrRestore() to clear the context exception when the current exception
is set:

    tmp_type = tstate->exc_type;
    tmp_value = tstate->exc_value;
    tmp_tb = tstate->exc_traceback;
    tstate->exc_type = 0;
    tstate->exc_value = 0;
    tstate->exc_traceback = 0;
    Py_XDECREF(tmp_type);
    Py_XDECREF(tmp_value);
    Py_XDECREF(tmp_tb);

While doing that, I also noticed that ReRaise is currently implemented like
this:

  static void __Pyx_ReRaise(void) {
    PyThreadState *tstate = PyThreadState_Get();
    PyObject *type = tstate->exc_type;
    PyObject *value = tstate->exc_value;
    PyObject *tb = tstate->exc_traceback;
    Py_XINCREF(type);
    Py_XINCREF(value);
    Py_XINCREF(tb);
    __Pyx_ErrRestore(type, value, tb);
  }

I wonder why this doesn't set exc_* to NULL either.

Both changes make the test suite pass in Py 3.0.1, and it still works in
Py2.6. Maybe Greg can tell us why it was originally implemented differently
and if there are potential issues?

In any case, this is more of a quick fix rather than the final solution.
The real fix would be to handle exception chaining correctly in Py3, i.e.
to set the context of an exception depending on where it is raised, and to
support the explicit "raise ... from ..." syntax to allow users to set the
cause.

http://trac.cython.org/cython_trac/ticket/217

Stefan
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to