Skip to content
This repository was archived by the owner on Nov 23, 2017. It is now read-only.

Commit 0bc2624

Browse files
committed
Raise when a user attempts to run a loop within another loop
1 parent fb96b0d commit 0bc2624

File tree

3 files changed

+24
-4
lines changed

3 files changed

+24
-4
lines changed

asyncio/base_events.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -394,13 +394,15 @@ def run_forever(self):
394394
self._check_closed()
395395
if self.is_running():
396396
raise RuntimeError('Event loop is running.')
397+
if events._get_running_loop() is not None:
398+
raise RuntimeError(
399+
'Cannot run the event loop while another loop is running')
397400
self._set_coroutine_wrapper(self._debug)
398401
self._thread_id = threading.get_ident()
399402
if self._asyncgens is not None:
400403
old_agen_hooks = sys.get_asyncgen_hooks()
401404
sys.set_asyncgen_hooks(firstiter=self._asyncgen_firstiter_hook,
402405
finalizer=self._asyncgen_finalizer_hook)
403-
old_loop = events._get_running_loop()
404406
try:
405407
events._set_running_loop(self)
406408
while True:
@@ -410,7 +412,7 @@ def run_forever(self):
410412
finally:
411413
self._stopping = False
412414
self._thread_id = None
413-
events._set_running_loop(old_loop)
415+
events._set_running_loop(None)
414416
self._set_coroutine_wrapper(False)
415417
if self._asyncgens is not None:
416418
sys.set_asyncgen_hooks(*old_agen_hooks)

asyncio/events.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -658,8 +658,8 @@ def set_event_loop_policy(policy):
658658
def get_event_loop():
659659
"""Return an asyncio event loop.
660660
661-
When called from coroutines, this function will always return the
662-
running event loop.
661+
When called from a coroutine or a callback (e.g. scheduled with call_soon
662+
or similar API), this function will always return the running event loop.
663663
664664
If there is no running event loop set, the function will return
665665
the result of `get_event_loop_policy().get_event_loop()` call.

tests/test_base_events.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1694,5 +1694,23 @@ def stop_loop_coro(loop):
16941694
"took .* seconds$")
16951695

16961696

1697+
class RunningLoopTests(unittest.TestCase):
1698+
1699+
def test_running_loop_within_a_loop(self):
1700+
@asyncio.coroutine
1701+
def runner(loop):
1702+
loop.run_forever()
1703+
1704+
loop = asyncio.new_event_loop()
1705+
outer_loop = asyncio.new_event_loop()
1706+
try:
1707+
with self.assertRaisesRegex(RuntimeError,
1708+
'while another loop is running'):
1709+
outer_loop.run_until_complete(runner(loop))
1710+
finally:
1711+
loop.close()
1712+
outer_loop.close()
1713+
1714+
16971715
if __name__ == '__main__':
16981716
unittest.main()

0 commit comments

Comments
 (0)