]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Support other yieldables in `yield list`/`multi_future`.
authorBen Darnell <ben@bendarnell.com>
Sun, 2 Aug 2015 21:39:46 +0000 (17:39 -0400)
committerBen Darnell <ben@bendarnell.com>
Sun, 2 Aug 2015 21:39:46 +0000 (17:39 -0400)
tornado/gen.py
tornado/test/gen_test.py

index e0ce1dde67c83eb4f7fce17257cc0ad58eba7063..9d4a59dc5010e5e8212337f3d03a0aecc366ff43 100644 (file)
@@ -624,11 +624,12 @@ class Multi(YieldPoint):
 def multi_future(children, quiet_exceptions=()):
     """Wait for multiple asynchronous futures in parallel.
 
-    Takes a list of ``Futures`` (but *not* other ``YieldPoints``) and returns
-    a new Future that resolves when all the other Futures are done.
-    If all the ``Futures`` succeeded, the returned Future's result is a list
-    of their results.  If any failed, the returned Future raises the exception
-    of the first one to fail.
+    Takes a list of ``Futures`` or other yieldable objects (with the
+    exception of the legacy `.YieldPoint` interfaces) and returns a
+    new Future that resolves when all the other Futures are done. If
+    all the ``Futures`` succeeded, the returned Future's result is a
+    list of their results. If any failed, the returned Future raises
+    the exception of the first one to fail.
 
     Instead of a list, the argument may also be a dictionary whose values are
     Futures, in which case a parallel dictionary is returned mapping the same
@@ -649,12 +650,16 @@ def multi_future(children, quiet_exceptions=()):
        If multiple ``Futures`` fail, any exceptions after the first (which is
        raised) will be logged. Added the ``quiet_exceptions``
        argument to suppress this logging for selected exception types.
+
+    .. versionchanged:: 4.3
+       Added support for other yieldable objects.
     """
     if isinstance(children, dict):
         keys = list(children.keys())
         children = children.values()
     else:
         keys = None
+    children = list(map(convert_yielded, children))
     assert all(is_future(i) for i in children)
     unfinished_children = set(children)
 
index 7b47f13021cdf7763b3d0c37600d6f77226f3c69..752cc8f9c00b1f0ceb7f687602de72ad6d62ba59 100644 (file)
@@ -746,6 +746,26 @@ class GenCoroutineTest(AsyncTestCase):
         self.assertEqual(result, 42)
         self.finished = True
 
+    @skipBefore35
+    @gen_test
+    def test_async_await_mixed_multi(self):
+        global_namespace = dict(globals(), **locals())
+        local_namespace = {}
+        exec(textwrap.dedent("""
+        async def f1():
+            await gen.Task(self.io_loop.add_callback)
+            return 42
+        """), global_namespace, local_namespace)
+
+        @gen.coroutine
+        def f2():
+            yield gen.Task(self.io_loop.add_callback)
+            raise gen.Return(43)
+
+        results = yield [local_namespace['f1'](), f2()]
+        self.assertEqual(results, [42, 43])
+        self.finished = True
+
     @gen_test
     def test_sync_return_no_value(self):
         @gen.coroutine