[Python-checkins] cpython: syncio.tasks: Fix CoroWrapper to workaround yield-from bug in CPython < 3.4.1

yury.selivanov python-checkins at python.org
Tue Apr 15 04:29:50 CEST 2014


http://hg.python.org/cpython/rev/13ff8645be57
changeset:   90314:13ff8645be57
parent:      90311:54f1168036f1
user:        Yury Selivanov <yselivanov at sprymix.com>
date:        Mon Apr 14 22:24:51 2014 -0400
summary:
  syncio.tasks: Fix CoroWrapper to workaround yield-from bug in CPython < 3.4.1

Closes issue #21209.

files:
  Lib/asyncio/tasks.py                |   5 ++-
  Lib/test/test_asyncio/test_tasks.py |  25 +++++++++++++++++
  Misc/NEWS                           |   3 ++
  3 files changed, 32 insertions(+), 1 deletions(-)


diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py
--- a/Lib/asyncio/tasks.py
+++ b/Lib/asyncio/tasks.py
@@ -49,7 +49,10 @@
     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
--- a/Lib/test/test_asyncio/test_tasks.py
+++ b/Lib/test/test_asyncio/test_tasks.py
@@ -1386,6 +1386,31 @@
         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
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -206,6 +206,9 @@
 - Issue #15916: doctest.DocTestSuite returns an empty unittest.TestSuite instead
   of raising ValueError if it finds no tests
 
+- Issue #21209: Fix asyncio.tasks.CoroWrapper to workaround a bug
+  in yield-from implementation in CPythons prior to 3.4.1.
+
 IDLE
 ----
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list