diff options
Diffstat (limited to 'Objects/genobject.c')
-rw-r--r-- | Objects/genobject.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/Objects/genobject.c b/Objects/genobject.c index 34ee7dcc1f..6e25f13475 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -2,8 +2,6 @@ #include "Python.h" #include "frameobject.h" -#include "genobject.h" -#include "ceval.h" #include "structmember.h" #include "opcode.h" @@ -102,6 +100,17 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc) if (!result || f->f_stacktop == NULL) { /* generator can't be rerun, so release the frame */ + /* first clean reference cycle through stored exception traceback */ + PyObject *t, *v, *tb; + t = f->f_exc_type; + v = f->f_exc_value; + tb = f->f_exc_traceback; + f->f_exc_type = NULL; + f->f_exc_value = NULL; + f->f_exc_traceback = NULL; + Py_XDECREF(t); + Py_XDECREF(v); + Py_XDECREF(tb); Py_DECREF(f); gen->gi_frame = NULL; } @@ -120,7 +129,7 @@ gen_send(PyGenObject *gen, PyObject *arg) } PyDoc_STRVAR(close_doc, -"close(arg) -> raise GeneratorExit inside generator."); +"close() -> raise GeneratorExit inside generator."); static PyObject * gen_close(PyGenObject *gen, PyObject *args) @@ -223,8 +232,9 @@ gen_throw(PyGenObject *gen, PyObject *args) /* First, check the traceback argument, replacing None with NULL. */ - if (tb == Py_None) + if (tb == Py_None) { tb = NULL; + } else if (tb != NULL && !PyTraceBack_Check(tb)) { PyErr_SetString(PyExc_TypeError, "throw() third argument must be a traceback object"); @@ -235,9 +245,8 @@ gen_throw(PyGenObject *gen, PyObject *args) Py_XINCREF(val); Py_XINCREF(tb); - if (PyExceptionClass_Check(typ)) { + if (PyExceptionClass_Check(typ)) PyErr_NormalizeException(&typ, &val, &tb); - } else if (PyExceptionInstance_Check(typ)) { /* Raising an instance. The value should be a dummy. */ @@ -252,6 +261,10 @@ gen_throw(PyGenObject *gen, PyObject *args) val = typ; typ = PyExceptionInstance_Class(typ); Py_INCREF(typ); + + if (tb == NULL) + /* Returns NULL if there's no traceback */ + tb = PyException_GetTraceback(val); } } else { |