From abae67ebc2897ca37df067f322d19e19d1ef6d88 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Mon, 11 Dec 2017 10:07:44 -0500 Subject: [PATCH] Add asyncio.get_running_loop() function. (#4782) --- Doc/library/asyncio-eventloops.rst | 7 +++++++ Lib/asyncio/events.py | 14 +++++++++++++- Lib/test/test_asyncio/test_events.py | 6 ++++++ .../2017-12-10-12-30-13.bpo-32269.Q85pKj.rst | 1 + 4 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2017-12-10-12-30-13.bpo-32269.Q85pKj.rst diff --git a/Doc/library/asyncio-eventloops.rst b/Doc/library/asyncio-eventloops.rst index 2097260e21..3051fde5b9 100644 --- a/Doc/library/asyncio-eventloops.rst +++ b/Doc/library/asyncio-eventloops.rst @@ -25,6 +25,13 @@ the execution of the process. Equivalent to calling ``get_event_loop_policy().new_event_loop()``. +.. function:: get_running_loop() + + Return the running event loop in the current OS thread. If there + is no running event loop a :exc:`RuntimeError` is raised. + + .. versionadded:: 3.7 + .. _asyncio-event-loops: diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py index 7db1ded8e8..e425b06e42 100644 --- a/Lib/asyncio/events.py +++ b/Lib/asyncio/events.py @@ -7,7 +7,8 @@ __all__ = ( 'get_event_loop_policy', 'set_event_loop_policy', 'get_event_loop', 'set_event_loop', 'new_event_loop', 'get_child_watcher', 'set_child_watcher', - '_set_running_loop', '_get_running_loop', + '_set_running_loop', 'get_running_loop', + '_get_running_loop', ) import functools @@ -646,6 +647,17 @@ class _RunningLoop(threading.local): _running_loop = _RunningLoop() +def get_running_loop(): + """Return the running event loop. Raise a RuntimeError if there is none. + + This function is thread-specific. + """ + loop = _get_running_loop() + if loop is None: + raise RuntimeError('no running event loop') + return loop + + def _get_running_loop(): """Return the running event loop or None. diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py index 39d5bb54a9..1315febe40 100644 --- a/Lib/test/test_asyncio/test_events.py +++ b/Lib/test/test_asyncio/test_events.py @@ -2733,10 +2733,13 @@ class PolicyTests(unittest.TestCase): try: asyncio.set_event_loop_policy(Policy()) loop = asyncio.new_event_loop() + with self.assertRaisesRegex(RuntimeError, 'no running'): + self.assertIs(asyncio.get_running_loop(), None) self.assertIs(asyncio._get_running_loop(), None) async def func(): self.assertIs(asyncio.get_event_loop(), loop) + self.assertIs(asyncio.get_running_loop(), loop) self.assertIs(asyncio._get_running_loop(), loop) loop.run_until_complete(func()) @@ -2745,6 +2748,9 @@ class PolicyTests(unittest.TestCase): if loop is not None: loop.close() + with self.assertRaisesRegex(RuntimeError, 'no running'): + self.assertIs(asyncio.get_running_loop(), None) + self.assertIs(asyncio._get_running_loop(), None) diff --git a/Misc/NEWS.d/next/Library/2017-12-10-12-30-13.bpo-32269.Q85pKj.rst b/Misc/NEWS.d/next/Library/2017-12-10-12-30-13.bpo-32269.Q85pKj.rst new file mode 100644 index 0000000000..9fa12446de --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-12-10-12-30-13.bpo-32269.Q85pKj.rst @@ -0,0 +1 @@ +Add asyncio.get_running_loop() function. -- 2.40.0