diff options
author | Yury Selivanov <yselivanov@sprymix.com> | 2015-05-09 15:44:30 (GMT) |
---|---|---|
committer | Yury Selivanov <yselivanov@sprymix.com> | 2015-05-09 15:44:30 (GMT) |
commit | 8170e8c0d12cb9414f3a3d3ca81a447b4afc5f26 (patch) | |
tree | d6353155110b49bf7953fd0d7d3f808512e8feb1 /Objects/genobject.c | |
parent | bd60e8dece89440ebdc80a19b2217d5ba2515124 (diff) | |
download | cpython-8170e8c0d12cb9414f3a3d3ca81a447b4afc5f26.zip cpython-8170e8c0d12cb9414f3a3d3ca81a447b4afc5f26.tar.gz cpython-8170e8c0d12cb9414f3a3d3ca81a447b4afc5f26.tar.bz2 |
PEP 479: Change StopIteration handling inside generators.
Closes issue #22906.
Diffstat (limited to 'Objects/genobject.c')
-rw-r--r-- | Objects/genobject.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/Objects/genobject.c b/Objects/genobject.c index 87060f3..5ae8512 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -130,6 +130,30 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc) } Py_CLEAR(result); } + else if (!result) { + /* Check for __future__ generator_stop and conditionally turn + * a leaking StopIteration into RuntimeError (with its cause + * set appropriately). */ + if ((((PyCodeObject *)gen->gi_code)->co_flags & + CO_FUTURE_GENERATOR_STOP) + && PyErr_ExceptionMatches(PyExc_StopIteration)) + { + PyObject *exc, *val, *val2, *tb; + PyErr_Fetch(&exc, &val, &tb); + PyErr_NormalizeException(&exc, &val, &tb); + if (tb != NULL) + PyException_SetTraceback(val, tb); + Py_DECREF(exc); + Py_XDECREF(tb); + PyErr_SetString(PyExc_RuntimeError, + "generator raised StopIteration"); + PyErr_Fetch(&exc, &val2, &tb); + PyErr_NormalizeException(&exc, &val2, &tb); + PyException_SetCause(val2, val); + PyException_SetContext(val2, val); + PyErr_Restore(exc, val2, tb); + } + } if (!result || f->f_stacktop == NULL) { /* generator can't be rerun, so release the frame */ |