gh-93453: No longer create an event loop in get_event_loop() (#98440)

asyncio.get_event_loop() now always return either running event loop or
the result of get_event_loop_policy().get_event_loop() call. The latter
should now raise an RuntimeError if no current event loop was set
instead of creating and setting a new event loop.

It affects also a number of asyncio functions and constructors which
call get_event_loop() implicitly: ensure_future(), shield(), gather(),
etc.

DeprecationWarning is no longer emitted if there is no running event loop but
the current event loop was set.

Co-authored-by: Łukasz Langa <lukasz@langa.pl>
This commit is contained in:
Serhiy Storchaka 2022-12-06 19:42:12 +02:00 committed by GitHub
parent b72014c783
commit fd38a2f0ec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 114 additions and 251 deletions

View file

@ -43,10 +43,12 @@ an event loop:
Get the current event loop.
If there is no current event loop set in the current OS thread,
the OS thread is main, and :func:`set_event_loop` has not yet
been called, asyncio will create a new event loop and set it as the
current one.
When called from a coroutine or a callback (e.g. scheduled with
call_soon or similar API), this function will always return the
running event loop.
If there is no running event loop set, the function will return
the result of calling ``get_event_loop_policy().get_event_loop()``.
Because this function has rather complex behavior (especially
when custom event loop policies are in use), using the
@ -57,11 +59,11 @@ an event loop:
instead of using these lower level functions to manually create and close an
event loop.
.. deprecated:: 3.10
Emits a deprecation warning if there is no running event loop.
In future Python releases, this function may become an alias of
:func:`get_running_loop` and will accordingly raise a
:exc:`RuntimeError` if there is no running event loop.
.. note::
In Python versions 3.10.0--3.10.8 and 3.11.0 this function
(and other functions which used it implicitly) emitted a
:exc:`DeprecationWarning` if there was no running event loop, even if
the current loop was set.
.. function:: set_event_loop(loop)

View file

@ -19,7 +19,7 @@ Obtaining the Event Loop
- The **preferred** function to get the running event loop.
* - :func:`asyncio.get_event_loop`
- Get an event loop instance (current or via the policy).
- Get an event loop instance (running or current via the current policy).
* - :func:`asyncio.set_event_loop`
- Set the event loop as current via the current policy.

View file

@ -116,6 +116,10 @@ asyncio ships with the following built-in policies:
On Windows, :class:`ProactorEventLoop` is now used by default.
.. versionchanged:: 3.12
:meth:`get_event_loop` now raises a :exc:`RuntimeError` if there is no
current event loop set.
.. class:: WindowsSelectorEventLoopPolicy

View file

@ -686,6 +686,18 @@ Changes in the Python API
around process-global resources, which are best managed from the main interpreter.
(Contributed by Dong-hee Na in :gh:`99127`.)
* :func:`asyncio.get_event_loop` and many other :mod:`asyncio` functions like
:func:`~asyncio.ensure_future`, :func:`~asyncio.shield` or
:func:`~asyncio.gather`, and also the
:meth:`~asyncio.BaseDefaultEventLoopPolicy.get_event_loop` method of
:class:`~asyncio.BaseDefaultEventLoopPolicy` now raise a :exc:`RuntimeError`
if called when there is no running event loop and the current event loop was
not set.
Previously they implicitly created and set a new current event loop.
:exc:`DeprecationWarning` is no longer emitted if there is no running
event loop but the current event loop is set in the policy.
(Contributed by Serhiy Storchaka in :gh:`93453`.)
Build Changes
=============

View file

@ -619,7 +619,7 @@ def get_event_loop(self):
Returns an event loop object implementing the BaseEventLoop interface,
or raises an exception in case no event loop has been set for the
current context and the current policy does not specify to create one.
current context.
It should never return None."""
raise NotImplementedError
@ -672,11 +672,6 @@ def get_event_loop(self):
Returns an instance of EventLoop or raises an exception.
"""
if (self._local._loop is None and
not self._local._set_called and
threading.current_thread() is threading.main_thread()):
self.set_event_loop(self.new_event_loop())
if self._local._loop is None:
raise RuntimeError('There is no current event loop in thread %r.'
% threading.current_thread().name)
@ -786,16 +781,9 @@ def get_event_loop():
the result of `get_event_loop_policy().get_event_loop()` call.
"""
# NOTE: this function is implemented in C (see _asynciomodule.c)
return _py__get_event_loop()
def _get_event_loop(stacklevel=3):
current_loop = _get_running_loop()
if current_loop is not None:
return current_loop
import warnings
warnings.warn('There is no current event loop',
DeprecationWarning, stacklevel=stacklevel)
return get_event_loop_policy().get_event_loop()
@ -825,7 +813,6 @@ def set_child_watcher(watcher):
_py__set_running_loop = _set_running_loop
_py_get_running_loop = get_running_loop
_py_get_event_loop = get_event_loop
_py__get_event_loop = _get_event_loop
try:
@ -833,7 +820,7 @@ def set_child_watcher(watcher):
# functions in asyncio. Pure Python implementation is
# about 4 times slower than C-accelerated.
from _asyncio import (_get_running_loop, _set_running_loop,
get_running_loop, get_event_loop, _get_event_loop)
get_running_loop, get_event_loop)
except ImportError:
pass
else:
@ -842,7 +829,6 @@ def set_child_watcher(watcher):
_c__set_running_loop = _set_running_loop
_c_get_running_loop = get_running_loop
_c_get_event_loop = get_event_loop
_c__get_event_loop = _get_event_loop
if hasattr(os, 'fork'):

View file

@ -77,7 +77,7 @@ def __init__(self, *, loop=None):
the default event loop.
"""
if loop is None:
self._loop = events._get_event_loop()
self._loop = events.get_event_loop()
else:
self._loop = loop
self._callbacks = []
@ -413,7 +413,7 @@ def wrap_future(future, *, loop=None):
assert isinstance(future, concurrent.futures.Future), \
f'concurrent.futures.Future is expected, got {future!r}'
if loop is None:
loop = events._get_event_loop()
loop = events.get_event_loop()
new_future = loop.create_future()
_chain_future(future, new_future)
return new_future

View file

@ -125,7 +125,7 @@ class FlowControlMixin(protocols.Protocol):
def __init__(self, loop=None):
if loop is None:
self._loop = events._get_event_loop(stacklevel=4)
self._loop = events.get_event_loop()
else:
self._loop = loop
self._paused = False
@ -404,7 +404,7 @@ def __init__(self, limit=_DEFAULT_LIMIT, loop=None):
self._limit = limit
if loop is None:
self._loop = events._get_event_loop()
self._loop = events.get_event_loop()
else:
self._loop = loop
self._buffer = bytearray()

View file

@ -582,7 +582,7 @@ def as_completed(fs, *, timeout=None):
from .queues import Queue # Import here to avoid circular import problem.
done = Queue()
loop = events._get_event_loop()
loop = events.get_event_loop()
todo = {ensure_future(f, loop=loop) for f in set(fs)}
timeout_handle = None
@ -668,7 +668,7 @@ def _ensure_future(coro_or_future, *, loop=None):
'is required')
if loop is None:
loop = events._get_event_loop(stacklevel=4)
loop = events.get_event_loop()
try:
return loop.create_task(coro_or_future)
except RuntimeError:
@ -749,7 +749,7 @@ def gather(*coros_or_futures, return_exceptions=False):
gather won't cancel any other awaitables.
"""
if not coros_or_futures:
loop = events._get_event_loop()
loop = events.get_event_loop()
outer = loop.create_future()
outer.set_result([])
return outer

View file

@ -746,7 +746,7 @@ async def coro():
def test_env_var_debug(self):
code = '\n'.join((
'import asyncio',
'loop = asyncio.get_event_loop()',
'loop = asyncio.new_event_loop()',
'print(loop.get_debug())'))
# Test with -E to not fail if the unit test was run with

View file

@ -2550,29 +2550,8 @@ def test_event_loop_policy(self):
def test_get_event_loop(self):
policy = asyncio.DefaultEventLoopPolicy()
self.assertIsNone(policy._local._loop)
loop = policy.get_event_loop()
self.assertIsInstance(loop, asyncio.AbstractEventLoop)
self.assertIs(policy._local._loop, loop)
self.assertIs(loop, policy.get_event_loop())
loop.close()
def test_get_event_loop_calls_set_event_loop(self):
policy = asyncio.DefaultEventLoopPolicy()
with mock.patch.object(
policy, "set_event_loop",
wraps=policy.set_event_loop) as m_set_event_loop:
loop = policy.get_event_loop()
# policy._local._loop must be set through .set_event_loop()
# (the unix DefaultEventLoopPolicy needs this call to attach
# the child watcher correctly)
m_set_event_loop.assert_called_with(loop)
loop.close()
with self.assertRaisesRegex(RuntimeError, 'no current event loop'):
policy.get_event_loop()
def test_get_event_loop_after_set_none(self):
policy = asyncio.DefaultEventLoopPolicy()
@ -2599,7 +2578,8 @@ def test_new_event_loop(self):
def test_set_event_loop(self):
policy = asyncio.DefaultEventLoopPolicy()
old_loop = policy.get_event_loop()
old_loop = policy.new_event_loop()
policy.set_event_loop(old_loop)
self.assertRaises(TypeError, policy.set_event_loop, object())
@ -2716,15 +2696,11 @@ def get_event_loop(self):
asyncio.set_event_loop_policy(Policy())
loop = asyncio.new_event_loop()
with self.assertWarns(DeprecationWarning) as cm:
with self.assertRaises(TestError):
asyncio.get_event_loop()
self.assertEqual(cm.filename, __file__)
with self.assertRaises(TestError):
asyncio.get_event_loop()
asyncio.set_event_loop(None)
with self.assertWarns(DeprecationWarning) as cm:
with self.assertRaises(TestError):
asyncio.get_event_loop()
self.assertEqual(cm.filename, __file__)
with self.assertRaises(TestError):
asyncio.get_event_loop()
with self.assertRaisesRegex(RuntimeError, 'no running'):
asyncio.get_running_loop()
@ -2738,16 +2714,11 @@ async def func():
loop.run_until_complete(func())
asyncio.set_event_loop(loop)
with self.assertWarns(DeprecationWarning) as cm:
with self.assertRaises(TestError):
asyncio.get_event_loop()
self.assertEqual(cm.filename, __file__)
with self.assertRaises(TestError):
asyncio.get_event_loop()
asyncio.set_event_loop(None)
with self.assertWarns(DeprecationWarning) as cm:
with self.assertRaises(TestError):
asyncio.get_event_loop()
self.assertEqual(cm.filename, __file__)
with self.assertRaises(TestError):
asyncio.get_event_loop()
finally:
asyncio.set_event_loop_policy(old_policy)
@ -2766,15 +2737,11 @@ def test_get_event_loop_returns_running_loop2(self):
loop = asyncio.new_event_loop()
self.addCleanup(loop.close)
with self.assertWarns(DeprecationWarning) as cm:
loop2 = asyncio.get_event_loop()
self.addCleanup(loop2.close)
self.assertEqual(cm.filename, __file__)
with self.assertRaisesRegex(RuntimeError, 'no current'):
asyncio.get_event_loop()
asyncio.set_event_loop(None)
with self.assertWarns(DeprecationWarning) as cm:
with self.assertRaisesRegex(RuntimeError, 'no current'):
asyncio.get_event_loop()
self.assertEqual(cm.filename, __file__)
with self.assertRaisesRegex(RuntimeError, 'no current'):
asyncio.get_event_loop()
with self.assertRaisesRegex(RuntimeError, 'no running'):
asyncio.get_running_loop()
@ -2788,15 +2755,11 @@ async def func():
loop.run_until_complete(func())
asyncio.set_event_loop(loop)
with self.assertWarns(DeprecationWarning) as cm:
self.assertIs(asyncio.get_event_loop(), loop)
self.assertEqual(cm.filename, __file__)
self.assertIs(asyncio.get_event_loop(), loop)
asyncio.set_event_loop(None)
with self.assertWarns(DeprecationWarning) as cm:
with self.assertRaisesRegex(RuntimeError, 'no current'):
asyncio.get_event_loop()
self.assertEqual(cm.filename, __file__)
with self.assertRaisesRegex(RuntimeError, 'no current'):
asyncio.get_event_loop()
finally:
asyncio.set_event_loop_policy(old_policy)

View file

@ -146,10 +146,8 @@ def test_initial_state(self):
self.assertTrue(f.cancelled())
def test_constructor_without_loop(self):
with self.assertWarns(DeprecationWarning) as cm:
with self.assertRaisesRegex(RuntimeError, 'There is no current event loop'):
self._new_future()
self.assertEqual(cm.filename, __file__)
with self.assertRaisesRegex(RuntimeError, 'no current event loop'):
self._new_future()
def test_constructor_use_running_loop(self):
async def test():
@ -159,12 +157,10 @@ async def test():
self.assertIs(f.get_loop(), self.loop)
def test_constructor_use_global_loop(self):
# Deprecated in 3.10
# Deprecated in 3.10, undeprecated in 3.12
asyncio.set_event_loop(self.loop)
self.addCleanup(asyncio.set_event_loop, None)
with self.assertWarns(DeprecationWarning) as cm:
f = self._new_future()
self.assertEqual(cm.filename, __file__)
f = self._new_future()
self.assertIs(f._loop, self.loop)
self.assertIs(f.get_loop(), self.loop)
@ -500,10 +496,8 @@ def run(arg):
return (arg, threading.get_ident())
ex = concurrent.futures.ThreadPoolExecutor(1)
f1 = ex.submit(run, 'oi')
with self.assertWarns(DeprecationWarning) as cm:
with self.assertRaises(RuntimeError):
asyncio.wrap_future(f1)
self.assertEqual(cm.filename, __file__)
with self.assertRaisesRegex(RuntimeError, 'no current event loop'):
asyncio.wrap_future(f1)
ex.shutdown(wait=True)
def test_wrap_future_use_running_loop(self):
@ -518,16 +512,14 @@ async def test():
ex.shutdown(wait=True)
def test_wrap_future_use_global_loop(self):
# Deprecated in 3.10
# Deprecated in 3.10, undeprecated in 3.12
asyncio.set_event_loop(self.loop)
self.addCleanup(asyncio.set_event_loop, None)
def run(arg):
return (arg, threading.get_ident())
ex = concurrent.futures.ThreadPoolExecutor(1)
f1 = ex.submit(run, 'oi')
with self.assertWarns(DeprecationWarning) as cm:
f2 = asyncio.wrap_future(f1)
self.assertEqual(cm.filename, __file__)
f2 = asyncio.wrap_future(f1)
self.assertIs(self.loop, f2._loop)
ex.shutdown(wait=True)

View file

@ -816,10 +816,8 @@ def test_read_all_from_pipe_reader(self):
self.assertEqual(data, b'data')
def test_streamreader_constructor_without_loop(self):
with self.assertWarns(DeprecationWarning) as cm:
with self.assertRaisesRegex(RuntimeError, 'There is no current event loop'):
asyncio.StreamReader()
self.assertEqual(cm.filename, __file__)
with self.assertRaisesRegex(RuntimeError, 'no current event loop'):
asyncio.StreamReader()
def test_streamreader_constructor_use_running_loop(self):
# asyncio issue #184: Ensure that StreamReaderProtocol constructor
@ -833,21 +831,17 @@ async def test():
def test_streamreader_constructor_use_global_loop(self):
# asyncio issue #184: Ensure that StreamReaderProtocol constructor
# retrieves the current loop if the loop parameter is not set
# Deprecated in 3.10
# Deprecated in 3.10, undeprecated in 3.12
self.addCleanup(asyncio.set_event_loop, None)
asyncio.set_event_loop(self.loop)
with self.assertWarns(DeprecationWarning) as cm:
reader = asyncio.StreamReader()
self.assertEqual(cm.filename, __file__)
reader = asyncio.StreamReader()
self.assertIs(reader._loop, self.loop)
def test_streamreaderprotocol_constructor_without_loop(self):
reader = mock.Mock()
with self.assertWarns(DeprecationWarning) as cm:
with self.assertRaisesRegex(RuntimeError, 'There is no current event loop'):
asyncio.StreamReaderProtocol(reader)
self.assertEqual(cm.filename, __file__)
with self.assertRaisesRegex(RuntimeError, 'no current event loop'):
asyncio.StreamReaderProtocol(reader)
def test_streamreaderprotocol_constructor_use_running_loop(self):
# asyncio issue #184: Ensure that StreamReaderProtocol constructor
@ -861,13 +855,11 @@ async def test():
def test_streamreaderprotocol_constructor_use_global_loop(self):
# asyncio issue #184: Ensure that StreamReaderProtocol constructor
# retrieves the current loop if the loop parameter is not set
# Deprecated in 3.10
# Deprecated in 3.10, undeprecated in 3.12
self.addCleanup(asyncio.set_event_loop, None)
asyncio.set_event_loop(self.loop)
reader = mock.Mock()
with self.assertWarns(DeprecationWarning) as cm:
protocol = asyncio.StreamReaderProtocol(reader)
self.assertEqual(cm.filename, __file__)
protocol = asyncio.StreamReaderProtocol(reader)
self.assertIs(protocol._loop, self.loop)
def test_multiple_drain(self):

View file

@ -196,10 +196,8 @@ async def notmuch():
a = notmuch()
self.addCleanup(a.close)
with self.assertWarns(DeprecationWarning) as cm:
with self.assertRaisesRegex(RuntimeError, 'There is no current event loop'):
asyncio.ensure_future(a)
self.assertEqual(cm.filename, __file__)
with self.assertRaisesRegex(RuntimeError, 'no current event loop'):
asyncio.ensure_future(a)
async def test():
return asyncio.ensure_future(notmuch())
@ -209,12 +207,10 @@ async def test():
self.assertTrue(t.done())
self.assertEqual(t.result(), 'ok')
# Deprecated in 3.10
# Deprecated in 3.10, undeprecated in 3.12
asyncio.set_event_loop(self.loop)
self.addCleanup(asyncio.set_event_loop, None)
with self.assertWarns(DeprecationWarning) as cm:
t = asyncio.ensure_future(notmuch())
self.assertEqual(cm.filename, __file__)
t = asyncio.ensure_future(notmuch())
self.assertIs(t._loop, self.loop)
self.loop.run_until_complete(t)
self.assertTrue(t.done())
@ -1532,10 +1528,8 @@ async def coro():
self.addCleanup(a.close)
futs = asyncio.as_completed([a])
with self.assertWarns(DeprecationWarning) as cm:
with self.assertRaisesRegex(RuntimeError, 'There is no current event loop'):
list(futs)
self.assertEqual(cm.filename, __file__)
with self.assertRaisesRegex(RuntimeError, 'no current event loop'):
list(futs)
def test_as_completed_coroutine_use_running_loop(self):
loop = self.new_test_loop()
@ -1965,10 +1959,8 @@ async def coro():
inner = coro()
self.addCleanup(inner.close)
with self.assertWarns(DeprecationWarning) as cm:
with self.assertRaisesRegex(RuntimeError, 'There is no current event loop'):
asyncio.shield(inner)
self.assertEqual(cm.filename, __file__)
with self.assertRaisesRegex(RuntimeError, 'no current event loop'):
asyncio.shield(inner)
def test_shield_coroutine_use_running_loop(self):
async def coro():
@ -1982,15 +1974,13 @@ async def test():
self.assertEqual(res, 42)
def test_shield_coroutine_use_global_loop(self):
# Deprecated in 3.10
# Deprecated in 3.10, undeprecated in 3.12
async def coro():
return 42
asyncio.set_event_loop(self.loop)
self.addCleanup(asyncio.set_event_loop, None)
with self.assertWarns(DeprecationWarning) as cm:
outer = asyncio.shield(coro())
self.assertEqual(cm.filename, __file__)
outer = asyncio.shield(coro())
self.assertEqual(outer._loop, self.loop)
res = self.loop.run_until_complete(outer)
self.assertEqual(res, 42)
@ -2827,7 +2817,7 @@ def test_current_task_no_running_loop(self):
self.assertIsNone(asyncio.current_task(loop=self.loop))
def test_current_task_no_running_loop_implicit(self):
with self.assertRaises(RuntimeError):
with self.assertRaisesRegex(RuntimeError, 'no running event loop'):
asyncio.current_task()
def test_current_task_with_implicit_loop(self):
@ -2991,10 +2981,8 @@ def _gather(self, *args, **kwargs):
return asyncio.gather(*args, **kwargs)
def test_constructor_empty_sequence_without_loop(self):
with self.assertWarns(DeprecationWarning) as cm:
with self.assertRaises(RuntimeError):
asyncio.gather()
self.assertEqual(cm.filename, __file__)
with self.assertRaisesRegex(RuntimeError, 'no current event loop'):
asyncio.gather()
def test_constructor_empty_sequence_use_running_loop(self):
async def gather():
@ -3007,12 +2995,10 @@ async def gather():
self.assertEqual(fut.result(), [])
def test_constructor_empty_sequence_use_global_loop(self):
# Deprecated in 3.10
# Deprecated in 3.10, undeprecated in 3.12
asyncio.set_event_loop(self.one_loop)
self.addCleanup(asyncio.set_event_loop, None)
with self.assertWarns(DeprecationWarning) as cm:
fut = asyncio.gather()
self.assertEqual(cm.filename, __file__)
fut = asyncio.gather()
self.assertIsInstance(fut, asyncio.Future)
self.assertIs(fut._loop, self.one_loop)
self._run_loop(self.one_loop)
@ -3100,10 +3086,8 @@ async def coro():
self.addCleanup(gen1.close)
gen2 = coro()
self.addCleanup(gen2.close)
with self.assertWarns(DeprecationWarning) as cm:
with self.assertRaises(RuntimeError):
asyncio.gather(gen1, gen2)
self.assertEqual(cm.filename, __file__)
with self.assertRaisesRegex(RuntimeError, 'no current event loop'):
asyncio.gather(gen1, gen2)
def test_constructor_use_running_loop(self):
async def coro():
@ -3117,16 +3101,14 @@ async def gather():
self.one_loop.run_until_complete(fut)
def test_constructor_use_global_loop(self):
# Deprecated in 3.10
# Deprecated in 3.10, undeprecated in 3.12
async def coro():
return 'abc'
asyncio.set_event_loop(self.other_loop)
self.addCleanup(asyncio.set_event_loop, None)
gen1 = coro()
gen2 = coro()
with self.assertWarns(DeprecationWarning) as cm:
fut = asyncio.gather(gen1, gen2)
self.assertEqual(cm.filename, __file__)
fut = asyncio.gather(gen1, gen2)
self.assertIs(fut._loop, self.other_loop)
self.other_loop.run_until_complete(fut)

View file

@ -1775,7 +1775,8 @@ def f():
def test_child_watcher_replace_mainloop_existing(self):
policy = self.create_policy()
loop = policy.get_event_loop()
loop = policy.new_event_loop()
policy.set_event_loop(loop)
# Explicitly setup SafeChildWatcher,
# default ThreadedChildWatcher has no _loop property
@ -1884,13 +1885,15 @@ async def test_fork_not_share_event_loop(self):
# child
try:
loop = asyncio.get_event_loop_policy().get_event_loop()
os.write(w, str(id(loop)).encode())
except RuntimeError:
os.write(w, b'NO LOOP')
except:
os.write(w, b'ERROR:' + ascii(sys.exc_info()).encode())
finally:
os._exit(0)
else:
# parent
child_loop = int(os.read(r, 100).decode())
self.assertNotEqual(child_loop, id(loop))
self.assertEqual(os.read(r, 100), b'NO LOOP')
wait_process(pid, exitcode=0)
@hashlib_helper.requires_hashdigest('md5')

View file

@ -2418,7 +2418,8 @@ class UnawaitedWarningDuringShutdownTest(unittest.TestCase):
def test_unawaited_warning_during_shutdown(self):
code = ("import asyncio\n"
"async def f(): pass\n"
"asyncio.gather(f())\n")
"async def t(): asyncio.gather(f())\n"
"asyncio.run(t())\n")
assert_python_ok("-c", code)
code = ("import sys\n"

View file

@ -0,0 +1,9 @@
:func:`asyncio.get_event_loop` and many other :mod:`asyncio` functions like
:func:`asyncio.ensure_future`, :func:`asyncio.shield` or
:func:`asyncio.gather`, and also the
:meth:`~asyncio.BaseDefaultEventLoopPolicy.get_event_loop` method of
:class:`asyncio.BaseDefaultEventLoopPolicy` now raise a :exc:`RuntimeError`
if called when there is no running event loop and the current event loop was
not set. Previously they implicitly created and set a new current event
loop. :exc:`DeprecationWarning` is no longer emitted if there is no running
event loop but the current event loop was set.

View file

@ -357,7 +357,7 @@ set_running_loop(asyncio_state *state, PyObject *loop)
static PyObject *
get_event_loop(asyncio_state *state, int stacklevel)
get_event_loop(asyncio_state *state)
{
PyObject *loop;
PyObject *policy;
@ -369,13 +369,6 @@ get_event_loop(asyncio_state *state, int stacklevel)
return loop;
}
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"There is no current event loop",
stacklevel))
{
return NULL;
}
policy = PyObject_CallNoArgs(state->asyncio_get_event_loop_policy);
if (policy == NULL) {
return NULL;
@ -538,7 +531,7 @@ future_init(FutureObj *fut, PyObject *loop)
if (loop == Py_None) {
asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut);
loop = get_event_loop(state, 1);
loop = get_event_loop(state);
if (loop == NULL) {
return -1;
}
@ -3229,20 +3222,7 @@ _asyncio_get_event_loop_impl(PyObject *module)
/*[clinic end generated code: output=2a2d8b2f824c648b input=9364bf2916c8655d]*/
{
asyncio_state *state = get_asyncio_state(module);
return get_event_loop(state, 1);
}
/*[clinic input]
_asyncio._get_event_loop
stacklevel: int = 3
[clinic start generated code]*/
static PyObject *
_asyncio__get_event_loop_impl(PyObject *module, int stacklevel)
/*[clinic end generated code: output=9c1d6d3c802e67c9 input=d17aebbd686f711d]*/
{
asyncio_state *state = get_asyncio_state(module);
return get_event_loop(state, stacklevel-1);
return get_event_loop(state);
}
/*[clinic input]
@ -3620,7 +3600,6 @@ PyDoc_STRVAR(module_doc, "Accelerator module for asyncio");
static PyMethodDef asyncio_methods[] = {
_ASYNCIO_GET_EVENT_LOOP_METHODDEF
_ASYNCIO__GET_EVENT_LOOP_METHODDEF
_ASYNCIO_GET_RUNNING_LOOP_METHODDEF
_ASYNCIO__GET_RUNNING_LOOP_METHODDEF
_ASYNCIO__SET_RUNNING_LOOP_METHODDEF

View file

@ -987,68 +987,6 @@ _asyncio_get_event_loop(PyObject *module, PyObject *Py_UNUSED(ignored))
return _asyncio_get_event_loop_impl(module);
}
PyDoc_STRVAR(_asyncio__get_event_loop__doc__,
"_get_event_loop($module, /, stacklevel=3)\n"
"--\n"
"\n");
#define _ASYNCIO__GET_EVENT_LOOP_METHODDEF \
{"_get_event_loop", _PyCFunction_CAST(_asyncio__get_event_loop), METH_FASTCALL|METH_KEYWORDS, _asyncio__get_event_loop__doc__},
static PyObject *
_asyncio__get_event_loop_impl(PyObject *module, int stacklevel);
static PyObject *
_asyncio__get_event_loop(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
#define NUM_KEYWORDS 1
static struct {
PyGC_Head _this_is_not_used;
PyObject_VAR_HEAD
PyObject *ob_item[NUM_KEYWORDS];
} _kwtuple = {
.ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
.ob_item = { &_Py_ID(stacklevel), },
};
#undef NUM_KEYWORDS
#define KWTUPLE (&_kwtuple.ob_base.ob_base)
#else // !Py_BUILD_CORE
# define KWTUPLE NULL
#endif // !Py_BUILD_CORE
static const char * const _keywords[] = {"stacklevel", NULL};
static _PyArg_Parser _parser = {
.keywords = _keywords,
.fname = "_get_event_loop",
.kwtuple = KWTUPLE,
};
#undef KWTUPLE
PyObject *argsbuf[1];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
int stacklevel = 3;
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
if (!args) {
goto exit;
}
if (!noptargs) {
goto skip_optional_pos;
}
stacklevel = _PyLong_AsInt(args[0]);
if (stacklevel == -1 && PyErr_Occurred()) {
goto exit;
}
skip_optional_pos:
return_value = _asyncio__get_event_loop_impl(module, stacklevel);
exit:
return return_value;
}
PyDoc_STRVAR(_asyncio_get_running_loop__doc__,
"get_running_loop($module, /)\n"
"--\n"
@ -1304,4 +1242,4 @@ _asyncio__leave_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs,
exit:
return return_value;
}
/*[clinic end generated code: output=550bc6603df89ed9 input=a9049054013a1b77]*/
/*[clinic end generated code: output=83580c190031241c input=a9049054013a1b77]*/