From: Vitja Makarov Date: Wed, 20 Apr 2011 12:47:55 +0000 (+0400) Subject: Swap exception context inside generators X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=100b7c06074f042fe051811316913f3719a9de3f;p=cython.git Swap exception context inside generators --- diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index db4e6993..54d19884 100755 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -8511,6 +8511,17 @@ static PyObject *__Pyx_Generator_Throw(PyObject *gen, PyObject *args, CYTHON_UNU typedef PyObject *(*__pyx_generator_body_t)(PyObject *, PyObject *); """, impl=""" +static CYTHON_INLINE void __Pyx_Generator_ExceptionClear(struct __pyx_Generator_object *self) +{ + Py_XDECREF(self->exc_type); + Py_XDECREF(self->exc_value); + Py_XDECREF(self->exc_traceback); + + self->exc_type = NULL; + self->exc_value = NULL; + self->exc_traceback = NULL; +} + static CYTHON_INLINE PyObject *__Pyx_Generator_SendEx(struct __pyx_Generator_object *self, PyObject *value) { PyObject *retval; @@ -8535,10 +8546,21 @@ static CYTHON_INLINE PyObject *__Pyx_Generator_SendEx(struct __pyx_Generator_obj return NULL; } + + if (value) + __Pyx_ExceptionSwap(&self->exc_type, &self->exc_value, &self->exc_traceback); + else + __Pyx_Generator_ExceptionClear(self); + self->is_running = 1; retval = self->body((PyObject *) self, value); self->is_running = 0; + if (retval) + __Pyx_ExceptionSwap(&self->exc_type, &self->exc_value, &self->exc_traceback); + else + __Pyx_Generator_ExceptionClear(self); + return retval; } @@ -8596,5 +8618,5 @@ static PyObject *__Pyx_Generator_Throw(PyObject *self, PyObject *args, CYTHON_UN } """, proto_block='utility_code_proto_before_types', -requires=[Nodes.raise_utility_code], +requires=[Nodes.raise_utility_code, Nodes.swap_exception_utility_code], ) diff --git a/Cython/Compiler/ParseTreeTransforms.py b/Cython/Compiler/ParseTreeTransforms.py index ca683e07..9ee649d1 100644 --- a/Cython/Compiler/ParseTreeTransforms.py +++ b/Cython/Compiler/ParseTreeTransforms.py @@ -1557,6 +1557,12 @@ class CreateClosureClasses(CythonTransform): is_cdef=True) klass.declare_var(pos=pos, name='resume_label', cname='resume_label', type=PyrexTypes.c_int_type, is_cdef=True) + klass.declare_var(pos=pos, name='exc_type', cname='exc_type', + type=PyrexTypes.py_object_type, is_cdef=True) + klass.declare_var(pos=pos, name='exc_value', cname='exc_value', + type=PyrexTypes.py_object_type, is_cdef=True) + klass.declare_var(pos=pos, name='exc_traceback', cname='exc_traceback', + type=PyrexTypes.py_object_type, is_cdef=True) import TypeSlots e = klass.declare_pyfunction('send', pos)