diff options
author | Yury Selivanov <yselivanov@sprymix.com> | 2015-12-11 16:33:59 (GMT) |
---|---|---|
committer | Yury Selivanov <yselivanov@sprymix.com> | 2015-12-11 16:33:59 (GMT) |
commit | 0ac3a0cd7932079724aaabbb0a078e1c17129068 (patch) | |
tree | 5aa52402d3fde41233b91ca88a04c03d6d6ed343 | |
parent | dddc781998da741511178c7cb4e303e3db5aac45 (diff) | |
download | cpython-0ac3a0cd7932079724aaabbb0a078e1c17129068.zip cpython-0ac3a0cd7932079724aaabbb0a078e1c17129068.tar.gz cpython-0ac3a0cd7932079724aaabbb0a078e1c17129068.tar.bz2 |
asyncio: Make Tasks check if Futures are attached to the same event loop
See https://github.com/python/asyncio/pull/303 for details
-rw-r--r-- | Lib/asyncio/tasks.py | 8 | ||||
-rw-r--r-- | Lib/test/test_asyncio/test_tasks.py | 15 |
2 files changed, 22 insertions, 1 deletions
diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index e6389d8..a2ab881 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -251,7 +251,13 @@ class Task(futures.Future): else: if isinstance(result, futures.Future): # Yielded Future must come from Future.__iter__(). - if result._blocking: + if result._loop is not self._loop: + self._loop.call_soon( + self._step, + RuntimeError( + 'Task {!r} got Future {!r} attached to a ' + 'different loop'.format(self, result))) + elif result._blocking: result._blocking = False result.add_done_callback(self._wakeup) self._fut_waiter = result diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 04d19ac..47b17d1 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -76,6 +76,21 @@ class TaskTests(test_utils.TestCase): def setUp(self): self.loop = self.new_test_loop() + def test_other_loop_future(self): + other_loop = asyncio.new_event_loop() + fut = asyncio.Future(loop=other_loop) + + @asyncio.coroutine + def run(fut): + yield from fut + + try: + with self.assertRaisesRegex(RuntimeError, + r'Task .* got Future .* attached'): + self.loop.run_until_complete(run(fut)) + finally: + other_loop.close() + def test_task_class(self): @asyncio.coroutine def notmuch(): |