summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/asyncio/tasks.py5
-rw-r--r--Lib/test/test_asyncio/test_tasks.py25
-rw-r--r--Misc/NEWS3
3 files changed, 32 insertions, 1 deletions
diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py
index 153f731..0366da3 100644
--- a/Lib/asyncio/tasks.py
+++ b/Lib/asyncio/tasks.py
@@ -49,7 +49,10 @@ class CoroWrapper:
def __next__(self):
return next(self.gen)
- def send(self, value):
+ def send(self, *value):
+ # We use `*value` because of a bug in CPythons prior
+ # to 3.4.1. See issue #21209 and test_yield_from_corowrapper
+ # for details. This workaround should be removed in 3.5.0.
return self.gen.send(value)
def throw(self, exc):
diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py
index ced3431..45de8ac 100644
--- a/Lib/test/test_asyncio/test_tasks.py
+++ b/Lib/test/test_asyncio/test_tasks.py
@@ -1386,6 +1386,31 @@ class TaskTests(unittest.TestCase):
self.assertRaises(ValueError, self.loop.run_until_complete,
asyncio.wait([], loop=self.loop))
+ def test_yield_from_corowrapper(self):
+ old_debug = asyncio.tasks._DEBUG
+ asyncio.tasks._DEBUG = True
+ try:
+ @asyncio.coroutine
+ def t1():
+ return (yield from t2())
+
+ @asyncio.coroutine
+ def t2():
+ f = asyncio.Future(loop=self.loop)
+ asyncio.Task(t3(f), loop=self.loop)
+ return (yield from f)
+
+ @asyncio.coroutine
+ def t3(f):
+ f.set_result((1, 2, 3))
+
+ task = asyncio.Task(t1(), loop=self.loop)
+ val = self.loop.run_until_complete(task)
+ self.assertEqual(val, (1, 2, 3))
+ finally:
+ asyncio.tasks._DEBUG = old_debug
+
+
class GatherTestsBase:
def setUp(self):
diff --git a/Misc/NEWS b/Misc/NEWS
index 8519b61..9cdc605 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -147,6 +147,9 @@ Library
positional-or-keyword arguments passed as keyword arguments become
keyword-only.
+- Issue #21209: Fix asyncio.tasks.CoroWrapper to workaround a bug
+ in yield-from implementation in CPythons prior to 3.4.1.
+
IDLE
----