summaryrefslogtreecommitdiff
path: root/Objects/genobject.c
diff options
context:
space:
mode:
authorYury Selivanov <yselivanov@sprymix.com>2015-05-22 11:16:47 -0400
committerYury Selivanov <yselivanov@sprymix.com>2015-05-22 11:16:47 -0400
commit6a0d5881d488263bdeb460d70a87b8e10b282c02 (patch)
tree4f9d87b97991091ca69ef6418fac9bd684fcfe4b /Objects/genobject.c
parent647cf1e9cabefeae8524838ab0bf2f9cc3ce16cc (diff)
downloadcpython-6a0d5881d488263bdeb460d70a87b8e10b282c02.tar.gz
Issue 24237: Raise PendingDeprecationWarning per PEP 479
Raise PendingDeprecationWarning when generator raises StopIteration and no __future__ import is used. Fix offenders in the stdlib and tests. See also issue 22906. Thanks to Nick Coghlan and Berker Peksag for reviews.
Diffstat (limited to 'Objects/genobject.c')
-rw-r--r--Objects/genobject.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/Objects/genobject.c b/Objects/genobject.c
index 555e4fd76e..8e5624d460 100644
--- a/Objects/genobject.c
+++ b/Objects/genobject.c
@@ -143,13 +143,12 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc)
}
Py_CLEAR(result);
}
- else if (!result) {
+ else if (!result && PyErr_ExceptionMatches(PyExc_StopIteration)) {
/* 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 &
+ if (((PyCodeObject *)gen->gi_code)->co_flags &
(CO_FUTURE_GENERATOR_STOP | CO_COROUTINE | CO_ITERABLE_COROUTINE))
- && PyErr_ExceptionMatches(PyExc_StopIteration))
{
PyObject *exc, *val, *val2, *tb;
PyErr_Fetch(&exc, &val, &tb);
@@ -167,6 +166,24 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc)
PyException_SetContext(val2, val);
PyErr_Restore(exc, val2, tb);
}
+ else {
+ PyObject *exc, *val, *tb;
+
+ /* Pop the exception before issuing a warning. */
+ PyErr_Fetch(&exc, &val, &tb);
+
+ if (PyErr_WarnFormat(PyExc_PendingDeprecationWarning, 1,
+ "generator '%.50S' raised StopIteration",
+ gen->gi_qualname)) {
+ /* Warning was converted to an error. */
+ Py_XDECREF(exc);
+ Py_XDECREF(val);
+ Py_XDECREF(tb);
+ }
+ else {
+ PyErr_Restore(exc, val, tb);
+ }
+ }
}
if (!result || f->f_stacktop == NULL) {