summaryrefslogtreecommitdiff
path: root/Objects/genobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/genobject.c')
-rw-r--r--Objects/genobject.c25
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 {