Issue #28492: Fix how StopIteration is raised in _asyncio.Future

This commit is contained in:
Yury Selivanov 2016-10-20 15:54:20 -04:00
parent 82919ec44f
commit a4b884f900
3 changed files with 34 additions and 2 deletions

View file

@ -787,9 +787,26 @@ FutureIter_iternext(futureiterobject *it)
res = FutureObj_result(fut, NULL);
if (res != NULL) {
// normal result
PyErr_SetObject(PyExc_StopIteration, res);
/* The result of the Future is not an exception.
We cunstruct an exception instance manually with
PyObject_CallFunctionObjArgs and pass it to PyErr_SetObject
(similarly to what genobject.c does).
This is to handle a situation when "res" is a tuple, in which
case PyErr_SetObject would set the value of StopIteration to
the first element of the tuple.
(See PyErr_SetObject/_PyErr_CreateException code for details.)
*/
PyObject *e = PyObject_CallFunctionObjArgs(
PyExc_StopIteration, res, NULL);
Py_DECREF(res);
if (e == NULL) {
return NULL;
}
PyErr_SetObject(PyExc_StopIteration, e);
Py_DECREF(e);
}
it->future = NULL;