From 3721737929376b384895ef39bc7859708fad1a19 Mon Sep 17 00:00:00 2001 From: Abhinav Gupta Date: Tue, 7 Apr 2015 11:57:45 -0700 Subject: [PATCH] Allow the same future multiple times in `multi_future` This prevents failures in cases like the following: f = yield [f, f] --- tornado/gen.py | 6 +++++- tornado/test/gen_test.py | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/tornado/gen.py b/tornado/gen.py index 6eac48309..e184c4337 100644 --- a/tornado/gen.py +++ b/tornado/gen.py @@ -671,8 +671,12 @@ def multi_future(children, quiet_exceptions=()): future.set_result(dict(zip(keys, result_list))) else: future.set_result(result_list) + + listening = set() for f in children: - f.add_done_callback(callback) + if f not in listening: + listening.add(f) + f.add_done_callback(callback) return future diff --git a/tornado/test/gen_test.py b/tornado/test/gen_test.py index 53c89ace5..d9188fec3 100644 --- a/tornado/test/gen_test.py +++ b/tornado/test/gen_test.py @@ -390,6 +390,12 @@ class GenEngineTest(AsyncTestCase): results = yield [self.async_future(1), self.async_future(2)] self.assertEqual(results, [1, 2]) + @gen_test + def test_multi_future_duplicate(self): + f = self.async_future(2) + results = yield [self.async_future(1), f, self.async_future(3), f] + self.assertEqual(results, [1, 2, 3, 2]) + @gen_test def test_multi_dict_future(self): results = yield dict(foo=self.async_future(1), bar=self.async_future(2)) -- 2.47.2