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:
parent
b72014c783
commit
fd38a2f0ec
@ -43,10 +43,12 @@ an event loop:
|
|||||||
|
|
||||||
Get the current event loop.
|
Get the current event loop.
|
||||||
|
|
||||||
If there is no current event loop set in the current OS thread,
|
When called from a coroutine or a callback (e.g. scheduled with
|
||||||
the OS thread is main, and :func:`set_event_loop` has not yet
|
call_soon or similar API), this function will always return the
|
||||||
been called, asyncio will create a new event loop and set it as the
|
running event loop.
|
||||||
current one.
|
|
||||||
|
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
|
Because this function has rather complex behavior (especially
|
||||||
when custom event loop policies are in use), using the
|
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
|
instead of using these lower level functions to manually create and close an
|
||||||
event loop.
|
event loop.
|
||||||
|
|
||||||
.. deprecated:: 3.10
|
.. note::
|
||||||
Emits a deprecation warning if there is no running event loop.
|
In Python versions 3.10.0--3.10.8 and 3.11.0 this function
|
||||||
In future Python releases, this function may become an alias of
|
(and other functions which used it implicitly) emitted a
|
||||||
:func:`get_running_loop` and will accordingly raise a
|
:exc:`DeprecationWarning` if there was no running event loop, even if
|
||||||
:exc:`RuntimeError` if there is no running event loop.
|
the current loop was set.
|
||||||
|
|
||||||
.. function:: set_event_loop(loop)
|
.. function:: set_event_loop(loop)
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ Obtaining the Event Loop
|
|||||||
- The **preferred** function to get the running event loop.
|
- The **preferred** function to get the running event loop.
|
||||||
|
|
||||||
* - :func:`asyncio.get_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`
|
* - :func:`asyncio.set_event_loop`
|
||||||
- Set the event loop as current via the current policy.
|
- Set the event loop as current via the current policy.
|
||||||
|
@ -116,6 +116,10 @@ asyncio ships with the following built-in policies:
|
|||||||
|
|
||||||
On Windows, :class:`ProactorEventLoop` is now used by default.
|
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
|
.. class:: WindowsSelectorEventLoopPolicy
|
||||||
|
|
||||||
|
@ -686,6 +686,18 @@ Changes in the Python API
|
|||||||
around process-global resources, which are best managed from the main interpreter.
|
around process-global resources, which are best managed from the main interpreter.
|
||||||
(Contributed by Dong-hee Na in :gh:`99127`.)
|
(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
|
Build Changes
|
||||||
=============
|
=============
|
||||||
|
@ -619,7 +619,7 @@ class AbstractEventLoopPolicy:
|
|||||||
|
|
||||||
Returns an event loop object implementing the BaseEventLoop interface,
|
Returns an event loop object implementing the BaseEventLoop interface,
|
||||||
or raises an exception in case no event loop has been set for the
|
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."""
|
It should never return None."""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
@ -672,11 +672,6 @@ class BaseDefaultEventLoopPolicy(AbstractEventLoopPolicy):
|
|||||||
|
|
||||||
Returns an instance of EventLoop or raises an exception.
|
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:
|
if self._local._loop is None:
|
||||||
raise RuntimeError('There is no current event loop in thread %r.'
|
raise RuntimeError('There is no current event loop in thread %r.'
|
||||||
% threading.current_thread().name)
|
% threading.current_thread().name)
|
||||||
@ -786,16 +781,9 @@ def get_event_loop():
|
|||||||
the result of `get_event_loop_policy().get_event_loop()` call.
|
the result of `get_event_loop_policy().get_event_loop()` call.
|
||||||
"""
|
"""
|
||||||
# NOTE: this function is implemented in C (see _asynciomodule.c)
|
# 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()
|
current_loop = _get_running_loop()
|
||||||
if current_loop is not None:
|
if current_loop is not None:
|
||||||
return current_loop
|
return current_loop
|
||||||
import warnings
|
|
||||||
warnings.warn('There is no current event loop',
|
|
||||||
DeprecationWarning, stacklevel=stacklevel)
|
|
||||||
return get_event_loop_policy().get_event_loop()
|
return get_event_loop_policy().get_event_loop()
|
||||||
|
|
||||||
|
|
||||||
@ -825,7 +813,6 @@ _py__get_running_loop = _get_running_loop
|
|||||||
_py__set_running_loop = _set_running_loop
|
_py__set_running_loop = _set_running_loop
|
||||||
_py_get_running_loop = get_running_loop
|
_py_get_running_loop = get_running_loop
|
||||||
_py_get_event_loop = get_event_loop
|
_py_get_event_loop = get_event_loop
|
||||||
_py__get_event_loop = _get_event_loop
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -833,7 +820,7 @@ try:
|
|||||||
# functions in asyncio. Pure Python implementation is
|
# functions in asyncio. Pure Python implementation is
|
||||||
# about 4 times slower than C-accelerated.
|
# about 4 times slower than C-accelerated.
|
||||||
from _asyncio import (_get_running_loop, _set_running_loop,
|
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:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
@ -842,7 +829,6 @@ else:
|
|||||||
_c__set_running_loop = _set_running_loop
|
_c__set_running_loop = _set_running_loop
|
||||||
_c_get_running_loop = get_running_loop
|
_c_get_running_loop = get_running_loop
|
||||||
_c_get_event_loop = get_event_loop
|
_c_get_event_loop = get_event_loop
|
||||||
_c__get_event_loop = _get_event_loop
|
|
||||||
|
|
||||||
|
|
||||||
if hasattr(os, 'fork'):
|
if hasattr(os, 'fork'):
|
||||||
|
@ -77,7 +77,7 @@ class Future:
|
|||||||
the default event loop.
|
the default event loop.
|
||||||
"""
|
"""
|
||||||
if loop is None:
|
if loop is None:
|
||||||
self._loop = events._get_event_loop()
|
self._loop = events.get_event_loop()
|
||||||
else:
|
else:
|
||||||
self._loop = loop
|
self._loop = loop
|
||||||
self._callbacks = []
|
self._callbacks = []
|
||||||
@ -413,7 +413,7 @@ def wrap_future(future, *, loop=None):
|
|||||||
assert isinstance(future, concurrent.futures.Future), \
|
assert isinstance(future, concurrent.futures.Future), \
|
||||||
f'concurrent.futures.Future is expected, got {future!r}'
|
f'concurrent.futures.Future is expected, got {future!r}'
|
||||||
if loop is None:
|
if loop is None:
|
||||||
loop = events._get_event_loop()
|
loop = events.get_event_loop()
|
||||||
new_future = loop.create_future()
|
new_future = loop.create_future()
|
||||||
_chain_future(future, new_future)
|
_chain_future(future, new_future)
|
||||||
return new_future
|
return new_future
|
||||||
|
@ -125,7 +125,7 @@ class FlowControlMixin(protocols.Protocol):
|
|||||||
|
|
||||||
def __init__(self, loop=None):
|
def __init__(self, loop=None):
|
||||||
if loop is None:
|
if loop is None:
|
||||||
self._loop = events._get_event_loop(stacklevel=4)
|
self._loop = events.get_event_loop()
|
||||||
else:
|
else:
|
||||||
self._loop = loop
|
self._loop = loop
|
||||||
self._paused = False
|
self._paused = False
|
||||||
@ -404,7 +404,7 @@ class StreamReader:
|
|||||||
|
|
||||||
self._limit = limit
|
self._limit = limit
|
||||||
if loop is None:
|
if loop is None:
|
||||||
self._loop = events._get_event_loop()
|
self._loop = events.get_event_loop()
|
||||||
else:
|
else:
|
||||||
self._loop = loop
|
self._loop = loop
|
||||||
self._buffer = bytearray()
|
self._buffer = bytearray()
|
||||||
|
@ -582,7 +582,7 @@ def as_completed(fs, *, timeout=None):
|
|||||||
from .queues import Queue # Import here to avoid circular import problem.
|
from .queues import Queue # Import here to avoid circular import problem.
|
||||||
done = Queue()
|
done = Queue()
|
||||||
|
|
||||||
loop = events._get_event_loop()
|
loop = events.get_event_loop()
|
||||||
todo = {ensure_future(f, loop=loop) for f in set(fs)}
|
todo = {ensure_future(f, loop=loop) for f in set(fs)}
|
||||||
timeout_handle = None
|
timeout_handle = None
|
||||||
|
|
||||||
@ -668,7 +668,7 @@ def _ensure_future(coro_or_future, *, loop=None):
|
|||||||
'is required')
|
'is required')
|
||||||
|
|
||||||
if loop is None:
|
if loop is None:
|
||||||
loop = events._get_event_loop(stacklevel=4)
|
loop = events.get_event_loop()
|
||||||
try:
|
try:
|
||||||
return loop.create_task(coro_or_future)
|
return loop.create_task(coro_or_future)
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
@ -749,7 +749,7 @@ def gather(*coros_or_futures, return_exceptions=False):
|
|||||||
gather won't cancel any other awaitables.
|
gather won't cancel any other awaitables.
|
||||||
"""
|
"""
|
||||||
if not coros_or_futures:
|
if not coros_or_futures:
|
||||||
loop = events._get_event_loop()
|
loop = events.get_event_loop()
|
||||||
outer = loop.create_future()
|
outer = loop.create_future()
|
||||||
outer.set_result([])
|
outer.set_result([])
|
||||||
return outer
|
return outer
|
||||||
|
@ -746,7 +746,7 @@ class BaseEventLoopTests(test_utils.TestCase):
|
|||||||
def test_env_var_debug(self):
|
def test_env_var_debug(self):
|
||||||
code = '\n'.join((
|
code = '\n'.join((
|
||||||
'import asyncio',
|
'import asyncio',
|
||||||
'loop = asyncio.get_event_loop()',
|
'loop = asyncio.new_event_loop()',
|
||||||
'print(loop.get_debug())'))
|
'print(loop.get_debug())'))
|
||||||
|
|
||||||
# Test with -E to not fail if the unit test was run with
|
# Test with -E to not fail if the unit test was run with
|
||||||
|
@ -2550,29 +2550,8 @@ class PolicyTests(unittest.TestCase):
|
|||||||
def test_get_event_loop(self):
|
def test_get_event_loop(self):
|
||||||
policy = asyncio.DefaultEventLoopPolicy()
|
policy = asyncio.DefaultEventLoopPolicy()
|
||||||
self.assertIsNone(policy._local._loop)
|
self.assertIsNone(policy._local._loop)
|
||||||
|
with self.assertRaisesRegex(RuntimeError, 'no current event loop'):
|
||||||
loop = policy.get_event_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()
|
|
||||||
|
|
||||||
def test_get_event_loop_after_set_none(self):
|
def test_get_event_loop_after_set_none(self):
|
||||||
policy = asyncio.DefaultEventLoopPolicy()
|
policy = asyncio.DefaultEventLoopPolicy()
|
||||||
@ -2599,7 +2578,8 @@ class PolicyTests(unittest.TestCase):
|
|||||||
|
|
||||||
def test_set_event_loop(self):
|
def test_set_event_loop(self):
|
||||||
policy = asyncio.DefaultEventLoopPolicy()
|
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())
|
self.assertRaises(TypeError, policy.set_event_loop, object())
|
||||||
|
|
||||||
@ -2716,15 +2696,11 @@ class GetEventLoopTestsMixin:
|
|||||||
asyncio.set_event_loop_policy(Policy())
|
asyncio.set_event_loop_policy(Policy())
|
||||||
loop = asyncio.new_event_loop()
|
loop = asyncio.new_event_loop()
|
||||||
|
|
||||||
with self.assertWarns(DeprecationWarning) as cm:
|
|
||||||
with self.assertRaises(TestError):
|
with self.assertRaises(TestError):
|
||||||
asyncio.get_event_loop()
|
asyncio.get_event_loop()
|
||||||
self.assertEqual(cm.filename, __file__)
|
|
||||||
asyncio.set_event_loop(None)
|
asyncio.set_event_loop(None)
|
||||||
with self.assertWarns(DeprecationWarning) as cm:
|
|
||||||
with self.assertRaises(TestError):
|
with self.assertRaises(TestError):
|
||||||
asyncio.get_event_loop()
|
asyncio.get_event_loop()
|
||||||
self.assertEqual(cm.filename, __file__)
|
|
||||||
|
|
||||||
with self.assertRaisesRegex(RuntimeError, 'no running'):
|
with self.assertRaisesRegex(RuntimeError, 'no running'):
|
||||||
asyncio.get_running_loop()
|
asyncio.get_running_loop()
|
||||||
@ -2738,16 +2714,11 @@ class GetEventLoopTestsMixin:
|
|||||||
loop.run_until_complete(func())
|
loop.run_until_complete(func())
|
||||||
|
|
||||||
asyncio.set_event_loop(loop)
|
asyncio.set_event_loop(loop)
|
||||||
with self.assertWarns(DeprecationWarning) as cm:
|
|
||||||
with self.assertRaises(TestError):
|
with self.assertRaises(TestError):
|
||||||
asyncio.get_event_loop()
|
asyncio.get_event_loop()
|
||||||
self.assertEqual(cm.filename, __file__)
|
|
||||||
|
|
||||||
asyncio.set_event_loop(None)
|
asyncio.set_event_loop(None)
|
||||||
with self.assertWarns(DeprecationWarning) as cm:
|
|
||||||
with self.assertRaises(TestError):
|
with self.assertRaises(TestError):
|
||||||
asyncio.get_event_loop()
|
asyncio.get_event_loop()
|
||||||
self.assertEqual(cm.filename, __file__)
|
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
asyncio.set_event_loop_policy(old_policy)
|
asyncio.set_event_loop_policy(old_policy)
|
||||||
@ -2766,15 +2737,11 @@ class GetEventLoopTestsMixin:
|
|||||||
loop = asyncio.new_event_loop()
|
loop = asyncio.new_event_loop()
|
||||||
self.addCleanup(loop.close)
|
self.addCleanup(loop.close)
|
||||||
|
|
||||||
with self.assertWarns(DeprecationWarning) as cm:
|
|
||||||
loop2 = asyncio.get_event_loop()
|
|
||||||
self.addCleanup(loop2.close)
|
|
||||||
self.assertEqual(cm.filename, __file__)
|
|
||||||
asyncio.set_event_loop(None)
|
|
||||||
with self.assertWarns(DeprecationWarning) as cm:
|
|
||||||
with self.assertRaisesRegex(RuntimeError, 'no current'):
|
with self.assertRaisesRegex(RuntimeError, 'no current'):
|
||||||
asyncio.get_event_loop()
|
asyncio.get_event_loop()
|
||||||
self.assertEqual(cm.filename, __file__)
|
asyncio.set_event_loop(None)
|
||||||
|
with self.assertRaisesRegex(RuntimeError, 'no current'):
|
||||||
|
asyncio.get_event_loop()
|
||||||
|
|
||||||
with self.assertRaisesRegex(RuntimeError, 'no running'):
|
with self.assertRaisesRegex(RuntimeError, 'no running'):
|
||||||
asyncio.get_running_loop()
|
asyncio.get_running_loop()
|
||||||
@ -2788,15 +2755,11 @@ class GetEventLoopTestsMixin:
|
|||||||
loop.run_until_complete(func())
|
loop.run_until_complete(func())
|
||||||
|
|
||||||
asyncio.set_event_loop(loop)
|
asyncio.set_event_loop(loop)
|
||||||
with self.assertWarns(DeprecationWarning) as cm:
|
|
||||||
self.assertIs(asyncio.get_event_loop(), loop)
|
self.assertIs(asyncio.get_event_loop(), loop)
|
||||||
self.assertEqual(cm.filename, __file__)
|
|
||||||
|
|
||||||
asyncio.set_event_loop(None)
|
asyncio.set_event_loop(None)
|
||||||
with self.assertWarns(DeprecationWarning) as cm:
|
|
||||||
with self.assertRaisesRegex(RuntimeError, 'no current'):
|
with self.assertRaisesRegex(RuntimeError, 'no current'):
|
||||||
asyncio.get_event_loop()
|
asyncio.get_event_loop()
|
||||||
self.assertEqual(cm.filename, __file__)
|
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
asyncio.set_event_loop_policy(old_policy)
|
asyncio.set_event_loop_policy(old_policy)
|
||||||
|
@ -146,10 +146,8 @@ class BaseFutureTests:
|
|||||||
self.assertTrue(f.cancelled())
|
self.assertTrue(f.cancelled())
|
||||||
|
|
||||||
def test_constructor_without_loop(self):
|
def test_constructor_without_loop(self):
|
||||||
with self.assertWarns(DeprecationWarning) as cm:
|
with self.assertRaisesRegex(RuntimeError, 'no current event loop'):
|
||||||
with self.assertRaisesRegex(RuntimeError, 'There is no current event loop'):
|
|
||||||
self._new_future()
|
self._new_future()
|
||||||
self.assertEqual(cm.filename, __file__)
|
|
||||||
|
|
||||||
def test_constructor_use_running_loop(self):
|
def test_constructor_use_running_loop(self):
|
||||||
async def test():
|
async def test():
|
||||||
@ -159,12 +157,10 @@ class BaseFutureTests:
|
|||||||
self.assertIs(f.get_loop(), self.loop)
|
self.assertIs(f.get_loop(), self.loop)
|
||||||
|
|
||||||
def test_constructor_use_global_loop(self):
|
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)
|
asyncio.set_event_loop(self.loop)
|
||||||
self.addCleanup(asyncio.set_event_loop, None)
|
self.addCleanup(asyncio.set_event_loop, None)
|
||||||
with self.assertWarns(DeprecationWarning) as cm:
|
|
||||||
f = self._new_future()
|
f = self._new_future()
|
||||||
self.assertEqual(cm.filename, __file__)
|
|
||||||
self.assertIs(f._loop, self.loop)
|
self.assertIs(f._loop, self.loop)
|
||||||
self.assertIs(f.get_loop(), self.loop)
|
self.assertIs(f.get_loop(), self.loop)
|
||||||
|
|
||||||
@ -500,10 +496,8 @@ class BaseFutureTests:
|
|||||||
return (arg, threading.get_ident())
|
return (arg, threading.get_ident())
|
||||||
ex = concurrent.futures.ThreadPoolExecutor(1)
|
ex = concurrent.futures.ThreadPoolExecutor(1)
|
||||||
f1 = ex.submit(run, 'oi')
|
f1 = ex.submit(run, 'oi')
|
||||||
with self.assertWarns(DeprecationWarning) as cm:
|
with self.assertRaisesRegex(RuntimeError, 'no current event loop'):
|
||||||
with self.assertRaises(RuntimeError):
|
|
||||||
asyncio.wrap_future(f1)
|
asyncio.wrap_future(f1)
|
||||||
self.assertEqual(cm.filename, __file__)
|
|
||||||
ex.shutdown(wait=True)
|
ex.shutdown(wait=True)
|
||||||
|
|
||||||
def test_wrap_future_use_running_loop(self):
|
def test_wrap_future_use_running_loop(self):
|
||||||
@ -518,16 +512,14 @@ class BaseFutureTests:
|
|||||||
ex.shutdown(wait=True)
|
ex.shutdown(wait=True)
|
||||||
|
|
||||||
def test_wrap_future_use_global_loop(self):
|
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)
|
asyncio.set_event_loop(self.loop)
|
||||||
self.addCleanup(asyncio.set_event_loop, None)
|
self.addCleanup(asyncio.set_event_loop, None)
|
||||||
def run(arg):
|
def run(arg):
|
||||||
return (arg, threading.get_ident())
|
return (arg, threading.get_ident())
|
||||||
ex = concurrent.futures.ThreadPoolExecutor(1)
|
ex = concurrent.futures.ThreadPoolExecutor(1)
|
||||||
f1 = ex.submit(run, 'oi')
|
f1 = ex.submit(run, 'oi')
|
||||||
with self.assertWarns(DeprecationWarning) as cm:
|
|
||||||
f2 = asyncio.wrap_future(f1)
|
f2 = asyncio.wrap_future(f1)
|
||||||
self.assertEqual(cm.filename, __file__)
|
|
||||||
self.assertIs(self.loop, f2._loop)
|
self.assertIs(self.loop, f2._loop)
|
||||||
ex.shutdown(wait=True)
|
ex.shutdown(wait=True)
|
||||||
|
|
||||||
|
@ -816,10 +816,8 @@ os.close(fd)
|
|||||||
self.assertEqual(data, b'data')
|
self.assertEqual(data, b'data')
|
||||||
|
|
||||||
def test_streamreader_constructor_without_loop(self):
|
def test_streamreader_constructor_without_loop(self):
|
||||||
with self.assertWarns(DeprecationWarning) as cm:
|
with self.assertRaisesRegex(RuntimeError, 'no current event loop'):
|
||||||
with self.assertRaisesRegex(RuntimeError, 'There is no current event loop'):
|
|
||||||
asyncio.StreamReader()
|
asyncio.StreamReader()
|
||||||
self.assertEqual(cm.filename, __file__)
|
|
||||||
|
|
||||||
def test_streamreader_constructor_use_running_loop(self):
|
def test_streamreader_constructor_use_running_loop(self):
|
||||||
# asyncio issue #184: Ensure that StreamReaderProtocol constructor
|
# asyncio issue #184: Ensure that StreamReaderProtocol constructor
|
||||||
@ -833,21 +831,17 @@ os.close(fd)
|
|||||||
def test_streamreader_constructor_use_global_loop(self):
|
def test_streamreader_constructor_use_global_loop(self):
|
||||||
# asyncio issue #184: Ensure that StreamReaderProtocol constructor
|
# asyncio issue #184: Ensure that StreamReaderProtocol constructor
|
||||||
# retrieves the current loop if the loop parameter is not set
|
# 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)
|
self.addCleanup(asyncio.set_event_loop, None)
|
||||||
asyncio.set_event_loop(self.loop)
|
asyncio.set_event_loop(self.loop)
|
||||||
with self.assertWarns(DeprecationWarning) as cm:
|
|
||||||
reader = asyncio.StreamReader()
|
reader = asyncio.StreamReader()
|
||||||
self.assertEqual(cm.filename, __file__)
|
|
||||||
self.assertIs(reader._loop, self.loop)
|
self.assertIs(reader._loop, self.loop)
|
||||||
|
|
||||||
|
|
||||||
def test_streamreaderprotocol_constructor_without_loop(self):
|
def test_streamreaderprotocol_constructor_without_loop(self):
|
||||||
reader = mock.Mock()
|
reader = mock.Mock()
|
||||||
with self.assertWarns(DeprecationWarning) as cm:
|
with self.assertRaisesRegex(RuntimeError, 'no current event loop'):
|
||||||
with self.assertRaisesRegex(RuntimeError, 'There is no current event loop'):
|
|
||||||
asyncio.StreamReaderProtocol(reader)
|
asyncio.StreamReaderProtocol(reader)
|
||||||
self.assertEqual(cm.filename, __file__)
|
|
||||||
|
|
||||||
def test_streamreaderprotocol_constructor_use_running_loop(self):
|
def test_streamreaderprotocol_constructor_use_running_loop(self):
|
||||||
# asyncio issue #184: Ensure that StreamReaderProtocol constructor
|
# asyncio issue #184: Ensure that StreamReaderProtocol constructor
|
||||||
@ -861,13 +855,11 @@ os.close(fd)
|
|||||||
def test_streamreaderprotocol_constructor_use_global_loop(self):
|
def test_streamreaderprotocol_constructor_use_global_loop(self):
|
||||||
# asyncio issue #184: Ensure that StreamReaderProtocol constructor
|
# asyncio issue #184: Ensure that StreamReaderProtocol constructor
|
||||||
# retrieves the current loop if the loop parameter is not set
|
# 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)
|
self.addCleanup(asyncio.set_event_loop, None)
|
||||||
asyncio.set_event_loop(self.loop)
|
asyncio.set_event_loop(self.loop)
|
||||||
reader = mock.Mock()
|
reader = mock.Mock()
|
||||||
with self.assertWarns(DeprecationWarning) as cm:
|
|
||||||
protocol = asyncio.StreamReaderProtocol(reader)
|
protocol = asyncio.StreamReaderProtocol(reader)
|
||||||
self.assertEqual(cm.filename, __file__)
|
|
||||||
self.assertIs(protocol._loop, self.loop)
|
self.assertIs(protocol._loop, self.loop)
|
||||||
|
|
||||||
def test_multiple_drain(self):
|
def test_multiple_drain(self):
|
||||||
|
@ -196,10 +196,8 @@ class BaseTaskTests:
|
|||||||
|
|
||||||
a = notmuch()
|
a = notmuch()
|
||||||
self.addCleanup(a.close)
|
self.addCleanup(a.close)
|
||||||
with self.assertWarns(DeprecationWarning) as cm:
|
with self.assertRaisesRegex(RuntimeError, 'no current event loop'):
|
||||||
with self.assertRaisesRegex(RuntimeError, 'There is no current event loop'):
|
|
||||||
asyncio.ensure_future(a)
|
asyncio.ensure_future(a)
|
||||||
self.assertEqual(cm.filename, __file__)
|
|
||||||
|
|
||||||
async def test():
|
async def test():
|
||||||
return asyncio.ensure_future(notmuch())
|
return asyncio.ensure_future(notmuch())
|
||||||
@ -209,12 +207,10 @@ class BaseTaskTests:
|
|||||||
self.assertTrue(t.done())
|
self.assertTrue(t.done())
|
||||||
self.assertEqual(t.result(), 'ok')
|
self.assertEqual(t.result(), 'ok')
|
||||||
|
|
||||||
# Deprecated in 3.10
|
# Deprecated in 3.10, undeprecated in 3.12
|
||||||
asyncio.set_event_loop(self.loop)
|
asyncio.set_event_loop(self.loop)
|
||||||
self.addCleanup(asyncio.set_event_loop, None)
|
self.addCleanup(asyncio.set_event_loop, None)
|
||||||
with self.assertWarns(DeprecationWarning) as cm:
|
|
||||||
t = asyncio.ensure_future(notmuch())
|
t = asyncio.ensure_future(notmuch())
|
||||||
self.assertEqual(cm.filename, __file__)
|
|
||||||
self.assertIs(t._loop, self.loop)
|
self.assertIs(t._loop, self.loop)
|
||||||
self.loop.run_until_complete(t)
|
self.loop.run_until_complete(t)
|
||||||
self.assertTrue(t.done())
|
self.assertTrue(t.done())
|
||||||
@ -1532,10 +1528,8 @@ class BaseTaskTests:
|
|||||||
self.addCleanup(a.close)
|
self.addCleanup(a.close)
|
||||||
|
|
||||||
futs = asyncio.as_completed([a])
|
futs = asyncio.as_completed([a])
|
||||||
with self.assertWarns(DeprecationWarning) as cm:
|
with self.assertRaisesRegex(RuntimeError, 'no current event loop'):
|
||||||
with self.assertRaisesRegex(RuntimeError, 'There is no current event loop'):
|
|
||||||
list(futs)
|
list(futs)
|
||||||
self.assertEqual(cm.filename, __file__)
|
|
||||||
|
|
||||||
def test_as_completed_coroutine_use_running_loop(self):
|
def test_as_completed_coroutine_use_running_loop(self):
|
||||||
loop = self.new_test_loop()
|
loop = self.new_test_loop()
|
||||||
@ -1965,10 +1959,8 @@ class BaseTaskTests:
|
|||||||
|
|
||||||
inner = coro()
|
inner = coro()
|
||||||
self.addCleanup(inner.close)
|
self.addCleanup(inner.close)
|
||||||
with self.assertWarns(DeprecationWarning) as cm:
|
with self.assertRaisesRegex(RuntimeError, 'no current event loop'):
|
||||||
with self.assertRaisesRegex(RuntimeError, 'There is no current event loop'):
|
|
||||||
asyncio.shield(inner)
|
asyncio.shield(inner)
|
||||||
self.assertEqual(cm.filename, __file__)
|
|
||||||
|
|
||||||
def test_shield_coroutine_use_running_loop(self):
|
def test_shield_coroutine_use_running_loop(self):
|
||||||
async def coro():
|
async def coro():
|
||||||
@ -1982,15 +1974,13 @@ class BaseTaskTests:
|
|||||||
self.assertEqual(res, 42)
|
self.assertEqual(res, 42)
|
||||||
|
|
||||||
def test_shield_coroutine_use_global_loop(self):
|
def test_shield_coroutine_use_global_loop(self):
|
||||||
# Deprecated in 3.10
|
# Deprecated in 3.10, undeprecated in 3.12
|
||||||
async def coro():
|
async def coro():
|
||||||
return 42
|
return 42
|
||||||
|
|
||||||
asyncio.set_event_loop(self.loop)
|
asyncio.set_event_loop(self.loop)
|
||||||
self.addCleanup(asyncio.set_event_loop, None)
|
self.addCleanup(asyncio.set_event_loop, None)
|
||||||
with self.assertWarns(DeprecationWarning) as cm:
|
|
||||||
outer = asyncio.shield(coro())
|
outer = asyncio.shield(coro())
|
||||||
self.assertEqual(cm.filename, __file__)
|
|
||||||
self.assertEqual(outer._loop, self.loop)
|
self.assertEqual(outer._loop, self.loop)
|
||||||
res = self.loop.run_until_complete(outer)
|
res = self.loop.run_until_complete(outer)
|
||||||
self.assertEqual(res, 42)
|
self.assertEqual(res, 42)
|
||||||
@ -2827,7 +2817,7 @@ class BaseCurrentLoopTests:
|
|||||||
self.assertIsNone(asyncio.current_task(loop=self.loop))
|
self.assertIsNone(asyncio.current_task(loop=self.loop))
|
||||||
|
|
||||||
def test_current_task_no_running_loop_implicit(self):
|
def test_current_task_no_running_loop_implicit(self):
|
||||||
with self.assertRaises(RuntimeError):
|
with self.assertRaisesRegex(RuntimeError, 'no running event loop'):
|
||||||
asyncio.current_task()
|
asyncio.current_task()
|
||||||
|
|
||||||
def test_current_task_with_implicit_loop(self):
|
def test_current_task_with_implicit_loop(self):
|
||||||
@ -2991,10 +2981,8 @@ class FutureGatherTests(GatherTestsBase, test_utils.TestCase):
|
|||||||
return asyncio.gather(*args, **kwargs)
|
return asyncio.gather(*args, **kwargs)
|
||||||
|
|
||||||
def test_constructor_empty_sequence_without_loop(self):
|
def test_constructor_empty_sequence_without_loop(self):
|
||||||
with self.assertWarns(DeprecationWarning) as cm:
|
with self.assertRaisesRegex(RuntimeError, 'no current event loop'):
|
||||||
with self.assertRaises(RuntimeError):
|
|
||||||
asyncio.gather()
|
asyncio.gather()
|
||||||
self.assertEqual(cm.filename, __file__)
|
|
||||||
|
|
||||||
def test_constructor_empty_sequence_use_running_loop(self):
|
def test_constructor_empty_sequence_use_running_loop(self):
|
||||||
async def gather():
|
async def gather():
|
||||||
@ -3007,12 +2995,10 @@ class FutureGatherTests(GatherTestsBase, test_utils.TestCase):
|
|||||||
self.assertEqual(fut.result(), [])
|
self.assertEqual(fut.result(), [])
|
||||||
|
|
||||||
def test_constructor_empty_sequence_use_global_loop(self):
|
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)
|
asyncio.set_event_loop(self.one_loop)
|
||||||
self.addCleanup(asyncio.set_event_loop, None)
|
self.addCleanup(asyncio.set_event_loop, None)
|
||||||
with self.assertWarns(DeprecationWarning) as cm:
|
|
||||||
fut = asyncio.gather()
|
fut = asyncio.gather()
|
||||||
self.assertEqual(cm.filename, __file__)
|
|
||||||
self.assertIsInstance(fut, asyncio.Future)
|
self.assertIsInstance(fut, asyncio.Future)
|
||||||
self.assertIs(fut._loop, self.one_loop)
|
self.assertIs(fut._loop, self.one_loop)
|
||||||
self._run_loop(self.one_loop)
|
self._run_loop(self.one_loop)
|
||||||
@ -3100,10 +3086,8 @@ class CoroutineGatherTests(GatherTestsBase, test_utils.TestCase):
|
|||||||
self.addCleanup(gen1.close)
|
self.addCleanup(gen1.close)
|
||||||
gen2 = coro()
|
gen2 = coro()
|
||||||
self.addCleanup(gen2.close)
|
self.addCleanup(gen2.close)
|
||||||
with self.assertWarns(DeprecationWarning) as cm:
|
with self.assertRaisesRegex(RuntimeError, 'no current event loop'):
|
||||||
with self.assertRaises(RuntimeError):
|
|
||||||
asyncio.gather(gen1, gen2)
|
asyncio.gather(gen1, gen2)
|
||||||
self.assertEqual(cm.filename, __file__)
|
|
||||||
|
|
||||||
def test_constructor_use_running_loop(self):
|
def test_constructor_use_running_loop(self):
|
||||||
async def coro():
|
async def coro():
|
||||||
@ -3117,16 +3101,14 @@ class CoroutineGatherTests(GatherTestsBase, test_utils.TestCase):
|
|||||||
self.one_loop.run_until_complete(fut)
|
self.one_loop.run_until_complete(fut)
|
||||||
|
|
||||||
def test_constructor_use_global_loop(self):
|
def test_constructor_use_global_loop(self):
|
||||||
# Deprecated in 3.10
|
# Deprecated in 3.10, undeprecated in 3.12
|
||||||
async def coro():
|
async def coro():
|
||||||
return 'abc'
|
return 'abc'
|
||||||
asyncio.set_event_loop(self.other_loop)
|
asyncio.set_event_loop(self.other_loop)
|
||||||
self.addCleanup(asyncio.set_event_loop, None)
|
self.addCleanup(asyncio.set_event_loop, None)
|
||||||
gen1 = coro()
|
gen1 = coro()
|
||||||
gen2 = coro()
|
gen2 = coro()
|
||||||
with self.assertWarns(DeprecationWarning) as cm:
|
|
||||||
fut = asyncio.gather(gen1, gen2)
|
fut = asyncio.gather(gen1, gen2)
|
||||||
self.assertEqual(cm.filename, __file__)
|
|
||||||
self.assertIs(fut._loop, self.other_loop)
|
self.assertIs(fut._loop, self.other_loop)
|
||||||
self.other_loop.run_until_complete(fut)
|
self.other_loop.run_until_complete(fut)
|
||||||
|
|
||||||
|
@ -1775,7 +1775,8 @@ class PolicyTests(unittest.TestCase):
|
|||||||
|
|
||||||
def test_child_watcher_replace_mainloop_existing(self):
|
def test_child_watcher_replace_mainloop_existing(self):
|
||||||
policy = self.create_policy()
|
policy = self.create_policy()
|
||||||
loop = policy.get_event_loop()
|
loop = policy.new_event_loop()
|
||||||
|
policy.set_event_loop(loop)
|
||||||
|
|
||||||
# Explicitly setup SafeChildWatcher,
|
# Explicitly setup SafeChildWatcher,
|
||||||
# default ThreadedChildWatcher has no _loop property
|
# default ThreadedChildWatcher has no _loop property
|
||||||
@ -1884,13 +1885,15 @@ class TestFork(unittest.IsolatedAsyncioTestCase):
|
|||||||
# child
|
# child
|
||||||
try:
|
try:
|
||||||
loop = asyncio.get_event_loop_policy().get_event_loop()
|
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:
|
finally:
|
||||||
os._exit(0)
|
os._exit(0)
|
||||||
else:
|
else:
|
||||||
# parent
|
# parent
|
||||||
child_loop = int(os.read(r, 100).decode())
|
self.assertEqual(os.read(r, 100), b'NO LOOP')
|
||||||
self.assertNotEqual(child_loop, id(loop))
|
|
||||||
wait_process(pid, exitcode=0)
|
wait_process(pid, exitcode=0)
|
||||||
|
|
||||||
@hashlib_helper.requires_hashdigest('md5')
|
@hashlib_helper.requires_hashdigest('md5')
|
||||||
|
@ -2418,7 +2418,8 @@ class UnawaitedWarningDuringShutdownTest(unittest.TestCase):
|
|||||||
def test_unawaited_warning_during_shutdown(self):
|
def test_unawaited_warning_during_shutdown(self):
|
||||||
code = ("import asyncio\n"
|
code = ("import asyncio\n"
|
||||||
"async def f(): pass\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)
|
assert_python_ok("-c", code)
|
||||||
|
|
||||||
code = ("import sys\n"
|
code = ("import sys\n"
|
||||||
|
@ -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.
|
@ -357,7 +357,7 @@ set_running_loop(asyncio_state *state, PyObject *loop)
|
|||||||
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
get_event_loop(asyncio_state *state, int stacklevel)
|
get_event_loop(asyncio_state *state)
|
||||||
{
|
{
|
||||||
PyObject *loop;
|
PyObject *loop;
|
||||||
PyObject *policy;
|
PyObject *policy;
|
||||||
@ -369,13 +369,6 @@ get_event_loop(asyncio_state *state, int stacklevel)
|
|||||||
return loop;
|
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);
|
policy = PyObject_CallNoArgs(state->asyncio_get_event_loop_policy);
|
||||||
if (policy == NULL) {
|
if (policy == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -538,7 +531,7 @@ future_init(FutureObj *fut, PyObject *loop)
|
|||||||
|
|
||||||
if (loop == Py_None) {
|
if (loop == Py_None) {
|
||||||
asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut);
|
asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut);
|
||||||
loop = get_event_loop(state, 1);
|
loop = get_event_loop(state);
|
||||||
if (loop == NULL) {
|
if (loop == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -3229,20 +3222,7 @@ _asyncio_get_event_loop_impl(PyObject *module)
|
|||||||
/*[clinic end generated code: output=2a2d8b2f824c648b input=9364bf2916c8655d]*/
|
/*[clinic end generated code: output=2a2d8b2f824c648b input=9364bf2916c8655d]*/
|
||||||
{
|
{
|
||||||
asyncio_state *state = get_asyncio_state(module);
|
asyncio_state *state = get_asyncio_state(module);
|
||||||
return get_event_loop(state, 1);
|
return get_event_loop(state);
|
||||||
}
|
|
||||||
|
|
||||||
/*[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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
@ -3620,7 +3600,6 @@ PyDoc_STRVAR(module_doc, "Accelerator module for asyncio");
|
|||||||
|
|
||||||
static PyMethodDef asyncio_methods[] = {
|
static PyMethodDef asyncio_methods[] = {
|
||||||
_ASYNCIO_GET_EVENT_LOOP_METHODDEF
|
_ASYNCIO_GET_EVENT_LOOP_METHODDEF
|
||||||
_ASYNCIO__GET_EVENT_LOOP_METHODDEF
|
|
||||||
_ASYNCIO_GET_RUNNING_LOOP_METHODDEF
|
_ASYNCIO_GET_RUNNING_LOOP_METHODDEF
|
||||||
_ASYNCIO__GET_RUNNING_LOOP_METHODDEF
|
_ASYNCIO__GET_RUNNING_LOOP_METHODDEF
|
||||||
_ASYNCIO__SET_RUNNING_LOOP_METHODDEF
|
_ASYNCIO__SET_RUNNING_LOOP_METHODDEF
|
||||||
|
64
Modules/clinic/_asynciomodule.c.h
generated
64
Modules/clinic/_asynciomodule.c.h
generated
@ -987,68 +987,6 @@ _asyncio_get_event_loop(PyObject *module, PyObject *Py_UNUSED(ignored))
|
|||||||
return _asyncio_get_event_loop_impl(module);
|
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__,
|
PyDoc_STRVAR(_asyncio_get_running_loop__doc__,
|
||||||
"get_running_loop($module, /)\n"
|
"get_running_loop($module, /)\n"
|
||||||
"--\n"
|
"--\n"
|
||||||
@ -1304,4 +1242,4 @@ _asyncio__leave_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs,
|
|||||||
exit:
|
exit:
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
/*[clinic end generated code: output=550bc6603df89ed9 input=a9049054013a1b77]*/
|
/*[clinic end generated code: output=83580c190031241c input=a9049054013a1b77]*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user