[Python-checkins] cpython (3.6): Issue #28492: Fix how StopIteration is raised in _asyncio.Future
yury.selivanov
python-checkins at python.org
Thu Oct 20 15:55:10 EDT 2016
https://hg.python.org/cpython/rev/cfe2109ce2c0
changeset: 104588:cfe2109ce2c0
branch: 3.6
parent: 104585:c60d41590054
user: Yury Selivanov <yury at magic.io>
date: Thu Oct 20 15:54:20 2016 -0400
summary:
Issue #28492: Fix how StopIteration is raised in _asyncio.Future
files:
Lib/test/test_asyncio/test_futures.py | 13 +++++++++
Misc/NEWS | 2 +
Modules/_asynciomodule.c | 21 +++++++++++++-
3 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py
--- a/Lib/test/test_asyncio/test_futures.py
+++ b/Lib/test/test_asyncio/test_futures.py
@@ -464,6 +464,19 @@
futures._set_result_unless_cancelled(fut, 2)
self.assertTrue(fut.cancelled())
+ def test_future_stop_iteration_args(self):
+ fut = asyncio.Future(loop=self.loop)
+ fut.set_result((1, 2))
+ fi = fut.__iter__()
+ result = None
+ try:
+ fi.send(None)
+ except StopIteration as ex:
+ result = ex.args[0]
+ else:
+ self.fail('StopIteration was expected')
+ self.assertEqual(result, (1, 2))
+
class FutureDoneCallbackTests(test_utils.TestCase):
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -28,6 +28,8 @@
- Issue #20766: Fix references leaked by pdb in the handling of SIGINT
handlers.
+- Issue #28492: Fix how StopIteration exception is raised in _asyncio.Future.
+
Build
-----
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -787,9 +787,26 @@
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;
--
Repository URL: https://hg.python.org/cpython
More information about the Python-checkins
mailing list