From e5ec05601331ae55748364851db5aec5aa370474 Mon Sep 17 00:00:00 2001 From: jimmylai Date: Sat, 20 May 2017 18:40:24 -0700 Subject: [PATCH 1/4] call remove_done_callback in finally section --- Lib/asyncio/base_events.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 3ff511be44a67e3..33b8f4887c6a64e 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -458,7 +458,8 @@ def run_until_complete(self, future): # local task. future.exception() raise - future.remove_done_callback(_run_until_complete_cb) + finally: + future.remove_done_callback(_run_until_complete_cb) if not future.done(): raise RuntimeError('Event loop stopped before Future completed.') From d0ccfacbd4974005068cdd6d66e1afc77e6deff6 Mon Sep 17 00:00:00 2001 From: Jimmy Lai Date: Mon, 4 Sep 2017 12:53:13 -0700 Subject: [PATCH 2/4] [asyncio] bpo-30423 bug: add regression test for orphan future causes "RuntimeError: Event loop stopped before Future completed." --- Lib/test/test_asyncio/test_base_events.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index 3f1ec651742e437..157bd78f068adcf 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -529,6 +529,20 @@ def test_run_until_complete_loop(self): self.assertRaises(ValueError, other_loop.run_until_complete, task) + def test_run_until_complete_loop_orphan_future_close_loop(self): + async def foo(sec=0): + await asyncio.sleep(sec) + self.loop.close() + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + try: + with mock.patch('asyncio.base_events.BaseEventLoop.run_forever', side_effect=Exception): + loop.run_until_complete(foo()) + except: + pass + loop.run_until_complete(foo(0.1)) + loop.close() + def test_subprocess_exec_invalid_args(self): args = [sys.executable, '-c', 'pass'] From 4bd4b45e5b0ff5272fdb6ed53a633dbfe8cbca44 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Wed, 1 Nov 2017 15:13:43 +0200 Subject: [PATCH 3/4] Update test_base_events.py --- Lib/test/test_asyncio/test_base_events.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index 157bd78f068adcf..e949e3de75b8354 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -536,7 +536,8 @@ async def foo(sec=0): loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) try: - with mock.patch('asyncio.base_events.BaseEventLoop.run_forever', side_effect=Exception): + with mock.patch('asyncio.base_events.BaseEventLoop.run_forever', + side_effect=Exception): loop.run_until_complete(foo()) except: pass From 58deb49509cb8969a6ee2780b642b9c5b3b28695 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Wed, 1 Nov 2017 15:18:52 +0200 Subject: [PATCH 4/4] Update test_base_events.py --- Lib/test/test_asyncio/test_base_events.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index e949e3de75b8354..c4f8283d1c2ae96 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -532,6 +532,7 @@ def test_run_until_complete_loop(self): def test_run_until_complete_loop_orphan_future_close_loop(self): async def foo(sec=0): await asyncio.sleep(sec) + self.loop.close() loop = asyncio.new_event_loop() asyncio.set_event_loop(loop)