mirror of
https://github.com/python/cpython
synced 2024-09-04 15:56:13 +00:00
bpo-39529: Deprecate creating new event loop in asyncio.get_event_loop() (GH-23554)
asyncio.get_event_loop() emits now a deprecation warning when it creates a new event loop. In future releases it will became an alias of asyncio.get_running_loop().
This commit is contained in:
parent
face87c94e
commit
172c0f2752
|
@ -53,6 +53,11 @@ an event loop:
|
|||
Consider also using the :func:`asyncio.run` function instead of using
|
||||
lower level functions to manually create and close an event loop.
|
||||
|
||||
.. deprecated:: 3.10
|
||||
Deprecation warning is emitted if there is no running event loop.
|
||||
If future Python releases this function will be an alias of
|
||||
:func:`get_running_loop`.
|
||||
|
||||
.. function:: set_event_loop(loop)
|
||||
|
||||
Set *loop* as a current event loop for the current OS thread.
|
||||
|
|
|
@ -57,12 +57,20 @@ Future Functions
|
|||
.. versionchanged:: 3.5.1
|
||||
The function accepts any :term:`awaitable` object.
|
||||
|
||||
.. deprecated:: 3.10
|
||||
Deprecation warning is emitted if *obj* is not a Future-like object
|
||||
and *loop* is not specified and there is no running event loop.
|
||||
|
||||
|
||||
.. function:: wrap_future(future, *, loop=None)
|
||||
|
||||
Wrap a :class:`concurrent.futures.Future` object in a
|
||||
:class:`asyncio.Future` object.
|
||||
|
||||
.. deprecated:: 3.10
|
||||
Deprecation warning is emitted if *future* is not a Future-like object
|
||||
and *loop* is not specified and there is no running event loop.
|
||||
|
||||
|
||||
Future Object
|
||||
=============
|
||||
|
@ -90,6 +98,10 @@ Future Object
|
|||
.. versionchanged:: 3.7
|
||||
Added support for the :mod:`contextvars` module.
|
||||
|
||||
.. deprecated:: 3.10
|
||||
Deprecation warning is emitted if *loop* is not specified
|
||||
and there is no running event loop.
|
||||
|
||||
.. method:: result()
|
||||
|
||||
Return the result of the Future.
|
||||
|
|
|
@ -397,6 +397,11 @@ Running Tasks Concurrently
|
|||
If the *gather* itself is cancelled, the cancellation is
|
||||
propagated regardless of *return_exceptions*.
|
||||
|
||||
.. deprecated:: 3.10
|
||||
Deprecation warning is emitted if no positional arguments are provided
|
||||
or not all positional arguments are Future-like objects
|
||||
and there is no running event loop.
|
||||
|
||||
|
||||
Shielding From Cancellation
|
||||
===========================
|
||||
|
@ -434,6 +439,10 @@ Shielding From Cancellation
|
|||
except CancelledError:
|
||||
res = None
|
||||
|
||||
.. deprecated:: 3.10
|
||||
Deprecation warning is emitted if *aw* is not Future-like object
|
||||
and there is no running event loop.
|
||||
|
||||
|
||||
Timeouts
|
||||
========
|
||||
|
@ -593,6 +602,10 @@ Waiting Primitives
|
|||
earliest_result = await coro
|
||||
# ...
|
||||
|
||||
.. deprecated:: 3.10
|
||||
Deprecation warning is emitted if not all awaitable objects in the *aws*
|
||||
iterable are Future-like objects and there is no running event loop.
|
||||
|
||||
|
||||
Running in Threads
|
||||
==================
|
||||
|
@ -775,6 +788,10 @@ Task Object
|
|||
.. deprecated-removed:: 3.8 3.10
|
||||
The *loop* parameter.
|
||||
|
||||
.. deprecated:: 3.10
|
||||
Deprecation warning is emitted if *loop* is not specified
|
||||
and there is no running event loop.
|
||||
|
||||
.. method:: cancel(msg=None)
|
||||
|
||||
Request the Task to be cancelled.
|
||||
|
|
|
@ -1349,6 +1349,19 @@ Deprecated
|
|||
scheduled for removal in Python 3.12.
|
||||
(Contributed by Erlend E. Aasland in :issue:`42264`.)
|
||||
|
||||
* :func:`asyncio.get_event_loop` emits now a deprecation warning if there is
|
||||
no running event loop. In future it will be an alias of
|
||||
:func:`~asyncio.get_running_loop`.
|
||||
:mod:`asyncio` functions which implicitly create a :class:`~asyncio.Future`
|
||||
or :class:`~asyncio.Task` objects emit now
|
||||
a deprecation warning if there is no running event loop and no explicit
|
||||
*loop* argument is passed: :func:`~asyncio.ensure_future`,
|
||||
:func:`~asyncio.wrap_future`, :func:`~asyncio.gather`,
|
||||
:func:`~asyncio.shield`, :func:`~asyncio.as_completed` and constructors of
|
||||
:class:`~asyncio.Future`, :class:`~asyncio.Task`,
|
||||
:class:`~asyncio.StreamReader`, :class:`~asyncio.StreamReaderProtocol`.
|
||||
(Contributed by Serhiy Storchaka in :issue:`39529`.)
|
||||
|
||||
* The undocumented built-in function ``sqlite3.enable_shared_cache`` is now
|
||||
deprecated, scheduled for removal in Python 3.12. Its use is strongly
|
||||
discouraged by the SQLite3 documentation. See `the SQLite3 docs
|
||||
|
|
|
@ -759,9 +759,16 @@ 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()
|
||||
|
||||
|
||||
|
@ -791,6 +798,7 @@ 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:
|
||||
|
@ -798,7 +806,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_running_loop, get_event_loop, _get_event_loop)
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
|
@ -807,3 +815,4 @@ 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
|
||||
|
|
|
@ -76,7 +76,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 = []
|
||||
|
@ -408,7 +408,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
|
||||
|
|
|
@ -125,7 +125,7 @@ class FlowControlMixin(protocols.Protocol):
|
|||
|
||||
def __init__(self, loop=None):
|
||||
if loop is None:
|
||||
self._loop = events.get_event_loop()
|
||||
self._loop = events._get_event_loop(stacklevel=4)
|
||||
else:
|
||||
self._loop = loop
|
||||
self._paused = False
|
||||
|
@ -283,9 +283,13 @@ def _get_close_waiter(self, stream):
|
|||
def __del__(self):
|
||||
# Prevent reports about unhandled exceptions.
|
||||
# Better than self._closed._log_traceback = False hack
|
||||
closed = self._closed
|
||||
if closed.done() and not closed.cancelled():
|
||||
closed.exception()
|
||||
try:
|
||||
closed = self._closed
|
||||
except AttributeError:
|
||||
pass # failed constructor
|
||||
else:
|
||||
if closed.done() and not closed.cancelled():
|
||||
closed.exception()
|
||||
|
||||
|
||||
class StreamWriter:
|
||||
|
@ -381,7 +385,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()
|
||||
|
|
|
@ -549,7 +549,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
|
||||
|
||||
|
@ -616,23 +616,26 @@ def ensure_future(coro_or_future, *, loop=None):
|
|||
|
||||
If the argument is a Future, it is returned directly.
|
||||
"""
|
||||
if coroutines.iscoroutine(coro_or_future):
|
||||
if loop is None:
|
||||
loop = events.get_event_loop()
|
||||
task = loop.create_task(coro_or_future)
|
||||
if task._source_traceback:
|
||||
del task._source_traceback[-1]
|
||||
return task
|
||||
elif futures.isfuture(coro_or_future):
|
||||
return _ensure_future(coro_or_future, loop=loop)
|
||||
|
||||
|
||||
def _ensure_future(coro_or_future, *, loop=None):
|
||||
if futures.isfuture(coro_or_future):
|
||||
if loop is not None and loop is not futures._get_loop(coro_or_future):
|
||||
raise ValueError('The future belongs to a different loop than '
|
||||
'the one specified as the loop argument')
|
||||
'the one specified as the loop argument')
|
||||
return coro_or_future
|
||||
elif inspect.isawaitable(coro_or_future):
|
||||
return ensure_future(_wrap_awaitable(coro_or_future), loop=loop)
|
||||
else:
|
||||
raise TypeError('An asyncio.Future, a coroutine or an awaitable is '
|
||||
'required')
|
||||
|
||||
if not coroutines.iscoroutine(coro_or_future):
|
||||
if inspect.isawaitable(coro_or_future):
|
||||
coro_or_future = _wrap_awaitable(coro_or_future)
|
||||
else:
|
||||
raise TypeError('An asyncio.Future, a coroutine or an awaitable '
|
||||
'is required')
|
||||
|
||||
if loop is None:
|
||||
loop = events._get_event_loop(stacklevel=4)
|
||||
return loop.create_task(coro_or_future)
|
||||
|
||||
|
||||
@types.coroutine
|
||||
|
@ -655,7 +658,8 @@ class _GatheringFuture(futures.Future):
|
|||
cancelled.
|
||||
"""
|
||||
|
||||
def __init__(self, children, *, loop=None):
|
||||
def __init__(self, children, *, loop):
|
||||
assert loop is not None
|
||||
super().__init__(loop=loop)
|
||||
self._children = children
|
||||
self._cancel_requested = False
|
||||
|
@ -706,7 +710,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
|
||||
|
@ -773,7 +777,7 @@ def _done_callback(fut):
|
|||
loop = None
|
||||
for arg in coros_or_futures:
|
||||
if arg not in arg_to_fut:
|
||||
fut = ensure_future(arg, loop=loop)
|
||||
fut = _ensure_future(arg, loop=loop)
|
||||
if loop is None:
|
||||
loop = futures._get_loop(fut)
|
||||
if fut is not arg:
|
||||
|
@ -823,7 +827,7 @@ def shield(arg):
|
|||
except CancelledError:
|
||||
res = None
|
||||
"""
|
||||
inner = ensure_future(arg)
|
||||
inner = _ensure_future(arg)
|
||||
if inner.done():
|
||||
# Shortcut.
|
||||
return inner
|
||||
|
|
|
@ -2702,14 +2702,18 @@ def get_event_loop(self):
|
|||
asyncio.set_event_loop_policy(Policy())
|
||||
loop = asyncio.new_event_loop()
|
||||
|
||||
with self.assertRaises(TestError):
|
||||
asyncio.get_event_loop()
|
||||
with self.assertWarns(DeprecationWarning) as cm:
|
||||
with self.assertRaises(TestError):
|
||||
asyncio.get_event_loop()
|
||||
self.assertEqual(cm.warnings[0].filename, __file__)
|
||||
asyncio.set_event_loop(None)
|
||||
with self.assertRaises(TestError):
|
||||
asyncio.get_event_loop()
|
||||
with self.assertWarns(DeprecationWarning) as cm:
|
||||
with self.assertRaises(TestError):
|
||||
asyncio.get_event_loop()
|
||||
self.assertEqual(cm.warnings[0].filename, __file__)
|
||||
|
||||
with self.assertRaisesRegex(RuntimeError, 'no running'):
|
||||
self.assertIs(asyncio.get_running_loop(), None)
|
||||
asyncio.get_running_loop()
|
||||
self.assertIs(asyncio._get_running_loop(), None)
|
||||
|
||||
async def func():
|
||||
|
@ -2720,12 +2724,16 @@ async def func():
|
|||
loop.run_until_complete(func())
|
||||
|
||||
asyncio.set_event_loop(loop)
|
||||
with self.assertRaises(TestError):
|
||||
asyncio.get_event_loop()
|
||||
with self.assertWarns(DeprecationWarning) as cm:
|
||||
with self.assertRaises(TestError):
|
||||
asyncio.get_event_loop()
|
||||
self.assertEqual(cm.warnings[0].filename, __file__)
|
||||
|
||||
asyncio.set_event_loop(None)
|
||||
with self.assertRaises(TestError):
|
||||
asyncio.get_event_loop()
|
||||
with self.assertWarns(DeprecationWarning) as cm:
|
||||
with self.assertRaises(TestError):
|
||||
asyncio.get_event_loop()
|
||||
self.assertEqual(cm.warnings[0].filename, __file__)
|
||||
|
||||
finally:
|
||||
asyncio.set_event_loop_policy(old_policy)
|
||||
|
@ -2733,7 +2741,56 @@ async def func():
|
|||
loop.close()
|
||||
|
||||
with self.assertRaisesRegex(RuntimeError, 'no running'):
|
||||
self.assertIs(asyncio.get_running_loop(), None)
|
||||
asyncio.get_running_loop()
|
||||
|
||||
self.assertIs(asyncio._get_running_loop(), None)
|
||||
|
||||
def test_get_event_loop_returns_running_loop2(self):
|
||||
old_policy = asyncio.get_event_loop_policy()
|
||||
try:
|
||||
asyncio.set_event_loop_policy(asyncio.DefaultEventLoopPolicy())
|
||||
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.warnings[0].filename, __file__)
|
||||
asyncio.set_event_loop(None)
|
||||
with self.assertWarns(DeprecationWarning) as cm:
|
||||
with self.assertRaisesRegex(RuntimeError, 'no current'):
|
||||
asyncio.get_event_loop()
|
||||
self.assertEqual(cm.warnings[0].filename, __file__)
|
||||
|
||||
with self.assertRaisesRegex(RuntimeError, 'no running'):
|
||||
asyncio.get_running_loop()
|
||||
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())
|
||||
|
||||
asyncio.set_event_loop(loop)
|
||||
with self.assertWarns(DeprecationWarning) as cm:
|
||||
self.assertIs(asyncio.get_event_loop(), loop)
|
||||
self.assertEqual(cm.warnings[0].filename, __file__)
|
||||
|
||||
asyncio.set_event_loop(None)
|
||||
with self.assertWarns(DeprecationWarning) as cm:
|
||||
with self.assertRaisesRegex(RuntimeError, 'no current'):
|
||||
asyncio.get_event_loop()
|
||||
self.assertEqual(cm.warnings[0].filename, __file__)
|
||||
|
||||
finally:
|
||||
asyncio.set_event_loop_policy(old_policy)
|
||||
if loop is not None:
|
||||
loop.close()
|
||||
|
||||
with self.assertRaisesRegex(RuntimeError, 'no running'):
|
||||
asyncio.get_running_loop()
|
||||
|
||||
self.assertIs(asyncio._get_running_loop(), None)
|
||||
|
||||
|
|
|
@ -139,9 +139,26 @@ def test_initial_state(self):
|
|||
f.cancel()
|
||||
self.assertTrue(f.cancelled())
|
||||
|
||||
def test_init_constructor_default_loop(self):
|
||||
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.warnings[0].filename, __file__)
|
||||
|
||||
def test_constructor_use_running_loop(self):
|
||||
async def test():
|
||||
return self._new_future()
|
||||
f = self.loop.run_until_complete(test())
|
||||
self.assertIs(f._loop, self.loop)
|
||||
self.assertIs(f.get_loop(), self.loop)
|
||||
|
||||
def test_constructor_use_global_loop(self):
|
||||
# Deprecated in 3.10
|
||||
asyncio.set_event_loop(self.loop)
|
||||
f = self._new_future()
|
||||
self.addCleanup(asyncio.set_event_loop, None)
|
||||
with self.assertWarns(DeprecationWarning) as cm:
|
||||
f = self._new_future()
|
||||
self.assertEqual(cm.warnings[0].filename, __file__)
|
||||
self.assertIs(f._loop, self.loop)
|
||||
self.assertIs(f.get_loop(), self.loop)
|
||||
|
||||
|
@ -472,16 +489,41 @@ def test_wrap_future_future(self):
|
|||
f2 = asyncio.wrap_future(f1)
|
||||
self.assertIs(f1, f2)
|
||||
|
||||
def test_wrap_future_without_loop(self):
|
||||
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.warnings[0].filename, __file__)
|
||||
ex.shutdown(wait=True)
|
||||
|
||||
def test_wrap_future_use_running_loop(self):
|
||||
def run(arg):
|
||||
return (arg, threading.get_ident())
|
||||
ex = concurrent.futures.ThreadPoolExecutor(1)
|
||||
f1 = ex.submit(run, 'oi')
|
||||
async def test():
|
||||
return asyncio.wrap_future(f1)
|
||||
f2 = self.loop.run_until_complete(test())
|
||||
self.assertIs(self.loop, f2._loop)
|
||||
ex.shutdown(wait=True)
|
||||
|
||||
def test_wrap_future_use_global_loop(self):
|
||||
with mock.patch('asyncio.futures.events') as events:
|
||||
events.get_event_loop = lambda: self.loop
|
||||
def run(arg):
|
||||
return (arg, threading.get_ident())
|
||||
ex = concurrent.futures.ThreadPoolExecutor(1)
|
||||
f1 = ex.submit(run, 'oi')
|
||||
# Deprecated in 3.10
|
||||
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.assertIs(self.loop, f2._loop)
|
||||
ex.shutdown(wait=True)
|
||||
self.assertEqual(cm.warnings[0].filename, __file__)
|
||||
self.assertIs(self.loop, f2._loop)
|
||||
ex.shutdown(wait=True)
|
||||
|
||||
def test_wrap_future_cancel(self):
|
||||
f1 = concurrent.futures.Future()
|
||||
|
|
|
@ -273,12 +273,12 @@ async def create_queue():
|
|||
queue._get_loop()
|
||||
return queue
|
||||
|
||||
q = self.loop.run_until_complete(create_queue())
|
||||
async def test():
|
||||
q = await create_queue()
|
||||
await asyncio.gather(producer(q, producer_num_items),
|
||||
consumer(q, producer_num_items))
|
||||
|
||||
self.loop.run_until_complete(
|
||||
asyncio.gather(producer(q, producer_num_items),
|
||||
consumer(q, producer_num_items)),
|
||||
)
|
||||
self.loop.run_until_complete(test())
|
||||
|
||||
def test_cancelled_getters_not_being_held_in_self_getters(self):
|
||||
def a_generator():
|
||||
|
@ -516,11 +516,14 @@ async def getter():
|
|||
for _ in range(num):
|
||||
item = queue.get_nowait()
|
||||
|
||||
t0 = putter(0)
|
||||
t1 = putter(1)
|
||||
t2 = putter(2)
|
||||
t3 = putter(3)
|
||||
self.loop.run_until_complete(asyncio.gather(getter(), t0, t1, t2, t3))
|
||||
async def test():
|
||||
t0 = putter(0)
|
||||
t1 = putter(1)
|
||||
t2 = putter(2)
|
||||
t3 = putter(3)
|
||||
await asyncio.gather(getter(), t0, t1, t2, t3)
|
||||
|
||||
self.loop.run_until_complete(test())
|
||||
|
||||
def test_cancelled_puts_not_being_held_in_self_putters(self):
|
||||
def a_generator():
|
||||
|
|
|
@ -40,11 +40,6 @@ def tearDown(self):
|
|||
gc.collect()
|
||||
super().tearDown()
|
||||
|
||||
@mock.patch('asyncio.streams.events')
|
||||
def test_ctor_global_loop(self, m_events):
|
||||
stream = asyncio.StreamReader()
|
||||
self.assertIs(stream._loop, m_events.get_event_loop.return_value)
|
||||
|
||||
def _basetest_open_connection(self, open_connection_fut):
|
||||
messages = []
|
||||
self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx))
|
||||
|
@ -751,23 +746,59 @@ def test_read_all_from_pipe_reader(self):
|
|||
data = self.loop.run_until_complete(reader.read(-1))
|
||||
self.assertEqual(data, b'data')
|
||||
|
||||
def test_streamreader_constructor(self):
|
||||
self.addCleanup(asyncio.set_event_loop, None)
|
||||
asyncio.set_event_loop(self.loop)
|
||||
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.warnings[0].filename, __file__)
|
||||
|
||||
def test_streamreader_constructor_use_running_loop(self):
|
||||
# asyncio issue #184: Ensure that StreamReaderProtocol constructor
|
||||
# retrieves the current loop if the loop parameter is not set
|
||||
reader = asyncio.StreamReader()
|
||||
async def test():
|
||||
return asyncio.StreamReader()
|
||||
|
||||
reader = self.loop.run_until_complete(test())
|
||||
self.assertIs(reader._loop, self.loop)
|
||||
|
||||
def test_streamreaderprotocol_constructor(self):
|
||||
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
|
||||
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.warnings[0].filename, __file__)
|
||||
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.warnings[0].filename, __file__)
|
||||
|
||||
def test_streamreaderprotocol_constructor_use_running_loop(self):
|
||||
# asyncio issue #184: Ensure that StreamReaderProtocol constructor
|
||||
# retrieves the current loop if the loop parameter is not set
|
||||
reader = mock.Mock()
|
||||
protocol = asyncio.StreamReaderProtocol(reader)
|
||||
async def test():
|
||||
return asyncio.StreamReaderProtocol(reader)
|
||||
protocol = self.loop.run_until_complete(test())
|
||||
self.assertIs(protocol._loop, self.loop)
|
||||
|
||||
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
|
||||
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.warnings[0].filename, __file__)
|
||||
self.assertIs(protocol._loop, self.loop)
|
||||
|
||||
def test_drain_raises(self):
|
||||
|
|
|
@ -200,22 +200,76 @@ async def notmuch():
|
|||
loop.close()
|
||||
|
||||
def test_ensure_future_coroutine(self):
|
||||
async def notmuch():
|
||||
return 'ok'
|
||||
t = asyncio.ensure_future(notmuch(), loop=self.loop)
|
||||
self.assertIs(t._loop, self.loop)
|
||||
self.loop.run_until_complete(t)
|
||||
self.assertTrue(t.done())
|
||||
self.assertEqual(t.result(), 'ok')
|
||||
|
||||
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.warnings[0].filename, __file__)
|
||||
|
||||
async def test():
|
||||
return asyncio.ensure_future(notmuch())
|
||||
t = self.loop.run_until_complete(test())
|
||||
self.assertIs(t._loop, self.loop)
|
||||
self.loop.run_until_complete(t)
|
||||
self.assertTrue(t.done())
|
||||
self.assertEqual(t.result(), 'ok')
|
||||
|
||||
# Deprecated in 3.10
|
||||
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.warnings[0].filename, __file__)
|
||||
self.assertIs(t._loop, self.loop)
|
||||
self.loop.run_until_complete(t)
|
||||
self.assertTrue(t.done())
|
||||
self.assertEqual(t.result(), 'ok')
|
||||
|
||||
def test_ensure_future_coroutine_2(self):
|
||||
with self.assertWarns(DeprecationWarning):
|
||||
@asyncio.coroutine
|
||||
def notmuch():
|
||||
return 'ok'
|
||||
t = asyncio.ensure_future(notmuch(), loop=self.loop)
|
||||
self.assertIs(t._loop, self.loop)
|
||||
self.loop.run_until_complete(t)
|
||||
self.assertTrue(t.done())
|
||||
self.assertEqual(t.result(), 'ok')
|
||||
self.assertIs(t._loop, self.loop)
|
||||
|
||||
loop = asyncio.new_event_loop()
|
||||
self.set_event_loop(loop)
|
||||
t = asyncio.ensure_future(notmuch(), loop=loop)
|
||||
self.assertIs(t._loop, loop)
|
||||
loop.run_until_complete(t)
|
||||
loop.close()
|
||||
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.warnings[0].filename, __file__)
|
||||
|
||||
async def test():
|
||||
return asyncio.ensure_future(notmuch())
|
||||
t = self.loop.run_until_complete(test())
|
||||
self.assertIs(t._loop, self.loop)
|
||||
self.loop.run_until_complete(t)
|
||||
self.assertTrue(t.done())
|
||||
self.assertEqual(t.result(), 'ok')
|
||||
|
||||
# Deprecated in 3.10
|
||||
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.warnings[0].filename, __file__)
|
||||
self.assertIs(t._loop, self.loop)
|
||||
self.loop.run_until_complete(t)
|
||||
self.assertTrue(t.done())
|
||||
self.assertEqual(t.result(), 'ok')
|
||||
|
||||
def test_ensure_future_future(self):
|
||||
f_orig = self.new_future(self.loop)
|
||||
|
@ -1078,33 +1132,6 @@ async def coro():
|
|||
res = loop.run_until_complete(asyncio.wait_for(coro(), timeout=None))
|
||||
self.assertEqual(res, 'done')
|
||||
|
||||
def test_wait_for_with_global_loop(self):
|
||||
|
||||
def gen():
|
||||
when = yield
|
||||
self.assertAlmostEqual(0.2, when)
|
||||
when = yield 0
|
||||
self.assertAlmostEqual(0.01, when)
|
||||
yield 0.01
|
||||
|
||||
loop = self.new_test_loop(gen)
|
||||
|
||||
async def foo():
|
||||
await asyncio.sleep(0.2)
|
||||
return 'done'
|
||||
|
||||
asyncio.set_event_loop(loop)
|
||||
try:
|
||||
fut = self.new_task(loop, foo())
|
||||
with self.assertRaises(asyncio.TimeoutError):
|
||||
loop.run_until_complete(asyncio.wait_for(fut, 0.01))
|
||||
finally:
|
||||
asyncio.set_event_loop(None)
|
||||
|
||||
self.assertAlmostEqual(0.01, loop.time())
|
||||
self.assertTrue(fut.done())
|
||||
self.assertTrue(fut.cancelled())
|
||||
|
||||
def test_wait_for_race_condition(self):
|
||||
|
||||
def gen():
|
||||
|
@ -1293,32 +1320,6 @@ async def foo():
|
|||
self.assertAlmostEqual(0.15, loop.time())
|
||||
self.assertEqual(res, 42)
|
||||
|
||||
def test_wait_with_global_loop(self):
|
||||
|
||||
def gen():
|
||||
when = yield
|
||||
self.assertAlmostEqual(0.01, when)
|
||||
when = yield 0
|
||||
self.assertAlmostEqual(0.015, when)
|
||||
yield 0.015
|
||||
|
||||
loop = self.new_test_loop(gen)
|
||||
|
||||
a = self.new_task(loop, asyncio.sleep(0.01))
|
||||
b = self.new_task(loop, asyncio.sleep(0.015))
|
||||
|
||||
async def foo():
|
||||
done, pending = await asyncio.wait([b, a])
|
||||
self.assertEqual(done, set([a, b]))
|
||||
self.assertEqual(pending, set())
|
||||
return 42
|
||||
|
||||
asyncio.set_event_loop(loop)
|
||||
res = loop.run_until_complete(
|
||||
self.new_task(loop, foo()))
|
||||
|
||||
self.assertEqual(res, 42)
|
||||
|
||||
def test_wait_duplicate_coroutines(self):
|
||||
|
||||
with self.assertWarns(DeprecationWarning):
|
||||
|
@ -1679,22 +1680,24 @@ def gen():
|
|||
yield 0
|
||||
|
||||
loop = self.new_test_loop(gen)
|
||||
asyncio.set_event_loop(loop)
|
||||
|
||||
a = asyncio.sleep(0.05, 'a')
|
||||
b = asyncio.sleep(0.10, 'b')
|
||||
fs = {a, b}
|
||||
|
||||
futs = list(asyncio.as_completed(fs))
|
||||
self.assertEqual(len(futs), 2)
|
||||
async def test():
|
||||
futs = list(asyncio.as_completed(fs))
|
||||
self.assertEqual(len(futs), 2)
|
||||
|
||||
x = loop.run_until_complete(futs[1])
|
||||
self.assertEqual(x, 'a')
|
||||
self.assertAlmostEqual(0.05, loop.time())
|
||||
loop.advance_time(0.05)
|
||||
y = loop.run_until_complete(futs[0])
|
||||
self.assertEqual(y, 'b')
|
||||
self.assertAlmostEqual(0.10, loop.time())
|
||||
x = await futs[1]
|
||||
self.assertEqual(x, 'a')
|
||||
self.assertAlmostEqual(0.05, loop.time())
|
||||
loop.advance_time(0.05)
|
||||
y = await futs[0]
|
||||
self.assertEqual(y, 'b')
|
||||
self.assertAlmostEqual(0.10, loop.time())
|
||||
|
||||
loop.run_until_complete(test())
|
||||
|
||||
def test_as_completed_concurrent(self):
|
||||
|
||||
|
@ -1705,20 +1708,22 @@ def gen():
|
|||
self.assertAlmostEqual(0.05, when)
|
||||
yield 0.05
|
||||
|
||||
loop = self.new_test_loop(gen)
|
||||
asyncio.set_event_loop(loop)
|
||||
|
||||
a = asyncio.sleep(0.05, 'a')
|
||||
b = asyncio.sleep(0.05, 'b')
|
||||
fs = {a, b}
|
||||
|
||||
futs = list(asyncio.as_completed(fs))
|
||||
self.assertEqual(len(futs), 2)
|
||||
waiter = asyncio.wait(futs)
|
||||
# Deprecation from passing coros in futs to asyncio.wait()
|
||||
with self.assertWarns(DeprecationWarning):
|
||||
done, pending = loop.run_until_complete(waiter)
|
||||
self.assertEqual(set(f.result() for f in done), {'a', 'b'})
|
||||
async def test():
|
||||
futs = list(asyncio.as_completed(fs))
|
||||
self.assertEqual(len(futs), 2)
|
||||
waiter = asyncio.wait(futs)
|
||||
# Deprecation from passing coros in futs to asyncio.wait()
|
||||
with self.assertWarns(DeprecationWarning) as cm:
|
||||
done, pending = await waiter
|
||||
self.assertEqual(cm.warnings[0].filename, __file__)
|
||||
self.assertEqual(set(f.result() for f in done), {'a', 'b'})
|
||||
|
||||
loop = self.new_test_loop(gen)
|
||||
loop.run_until_complete(test())
|
||||
|
||||
def test_as_completed_duplicate_coroutines(self):
|
||||
|
||||
|
@ -1742,6 +1747,47 @@ def runner():
|
|||
self.assertEqual(set(result), {'ham', 'spam'})
|
||||
self.assertEqual(len(result), 2)
|
||||
|
||||
def test_as_completed_coroutine_without_loop(self):
|
||||
async def coro():
|
||||
return 42
|
||||
|
||||
a = 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.warnings[0].filename, __file__)
|
||||
|
||||
def test_as_completed_coroutine_use_running_loop(self):
|
||||
loop = self.new_test_loop()
|
||||
|
||||
async def coro():
|
||||
return 42
|
||||
|
||||
async def test():
|
||||
futs = list(asyncio.as_completed([coro()]))
|
||||
self.assertEqual(len(futs), 1)
|
||||
self.assertEqual(await futs[0], 42)
|
||||
|
||||
loop.run_until_complete(test())
|
||||
|
||||
def test_as_completed_coroutine_use_global_loop(self):
|
||||
# Deprecated in 3.10
|
||||
async def coro():
|
||||
return 42
|
||||
|
||||
loop = self.new_test_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
self.addCleanup(asyncio.set_event_loop, None)
|
||||
futs = asyncio.as_completed([coro()])
|
||||
with self.assertWarns(DeprecationWarning) as cm:
|
||||
futs = list(futs)
|
||||
self.assertEqual(cm.warnings[0].filename, __file__)
|
||||
self.assertEqual(len(futs), 1)
|
||||
self.assertEqual(loop.run_until_complete(futs[0]), 42)
|
||||
|
||||
def test_sleep(self):
|
||||
|
||||
def gen():
|
||||
|
@ -2201,6 +2247,42 @@ def test_gather_shield(self):
|
|||
child2.set_result(2)
|
||||
test_utils.run_briefly(self.loop)
|
||||
|
||||
def test_shield_coroutine_without_loop(self):
|
||||
async def coro():
|
||||
return 42
|
||||
|
||||
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.warnings[0].filename, __file__)
|
||||
|
||||
def test_shield_coroutine_use_running_loop(self):
|
||||
async def coro():
|
||||
return 42
|
||||
|
||||
async def test():
|
||||
return asyncio.shield(coro())
|
||||
outer = self.loop.run_until_complete(test())
|
||||
self.assertEqual(outer._loop, self.loop)
|
||||
res = self.loop.run_until_complete(outer)
|
||||
self.assertEqual(res, 42)
|
||||
|
||||
def test_shield_coroutine_use_global_loop(self):
|
||||
# Deprecated in 3.10
|
||||
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.warnings[0].filename, __file__)
|
||||
self.assertEqual(outer._loop, self.loop)
|
||||
res = self.loop.run_until_complete(outer)
|
||||
self.assertEqual(res, 42)
|
||||
|
||||
def test_as_completed_invalid_args(self):
|
||||
fut = self.new_future(self.loop)
|
||||
|
||||
|
@ -2507,16 +2589,17 @@ def test_cancel_gather_1(self):
|
|||
"""Ensure that a gathering future refuses to be cancelled once all
|
||||
children are done"""
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
self.addCleanup(loop.close)
|
||||
|
||||
fut = self.new_future(loop)
|
||||
# The indirection fut->child_coro is needed since otherwise the
|
||||
# gathering task is done at the same time as the child future
|
||||
def child_coro():
|
||||
return (yield from fut)
|
||||
gather_future = asyncio.gather(child_coro())
|
||||
gather_task = asyncio.ensure_future(gather_future, loop=loop)
|
||||
async def create():
|
||||
# The indirection fut->child_coro is needed since otherwise the
|
||||
# gathering task is done at the same time as the child future
|
||||
def child_coro():
|
||||
return (yield from fut)
|
||||
gather_future = asyncio.gather(child_coro())
|
||||
return asyncio.ensure_future(gather_future)
|
||||
gather_task = loop.run_until_complete(create())
|
||||
|
||||
cancel_result = None
|
||||
def cancelling_callback(_):
|
||||
|
@ -3222,7 +3305,7 @@ def _run_loop(self, loop):
|
|||
|
||||
def _check_success(self, **kwargs):
|
||||
a, b, c = [self.one_loop.create_future() for i in range(3)]
|
||||
fut = asyncio.gather(*self.wrap_futures(a, b, c), **kwargs)
|
||||
fut = self._gather(*self.wrap_futures(a, b, c), **kwargs)
|
||||
cb = test_utils.MockCallback()
|
||||
fut.add_done_callback(cb)
|
||||
b.set_result(1)
|
||||
|
@ -3244,7 +3327,7 @@ def test_result_exception_success(self):
|
|||
|
||||
def test_one_exception(self):
|
||||
a, b, c, d, e = [self.one_loop.create_future() for i in range(5)]
|
||||
fut = asyncio.gather(*self.wrap_futures(a, b, c, d, e))
|
||||
fut = self._gather(*self.wrap_futures(a, b, c, d, e))
|
||||
cb = test_utils.MockCallback()
|
||||
fut.add_done_callback(cb)
|
||||
exc = ZeroDivisionError()
|
||||
|
@ -3262,8 +3345,8 @@ def test_one_exception(self):
|
|||
|
||||
def test_return_exceptions(self):
|
||||
a, b, c, d = [self.one_loop.create_future() for i in range(4)]
|
||||
fut = asyncio.gather(*self.wrap_futures(a, b, c, d),
|
||||
return_exceptions=True)
|
||||
fut = self._gather(*self.wrap_futures(a, b, c, d),
|
||||
return_exceptions=True)
|
||||
cb = test_utils.MockCallback()
|
||||
fut.add_done_callback(cb)
|
||||
exc = ZeroDivisionError()
|
||||
|
@ -3315,21 +3398,37 @@ class FutureGatherTests(GatherTestsBase, test_utils.TestCase):
|
|||
def wrap_futures(self, *futures):
|
||||
return futures
|
||||
|
||||
def _check_empty_sequence(self, seq_or_iter):
|
||||
asyncio.set_event_loop(self.one_loop)
|
||||
self.addCleanup(asyncio.set_event_loop, None)
|
||||
fut = asyncio.gather(*seq_or_iter)
|
||||
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.warnings[0].filename, __file__)
|
||||
|
||||
def test_constructor_empty_sequence_use_running_loop(self):
|
||||
async def gather():
|
||||
return asyncio.gather()
|
||||
fut = self.one_loop.run_until_complete(gather())
|
||||
self.assertIsInstance(fut, asyncio.Future)
|
||||
self.assertIs(fut._loop, self.one_loop)
|
||||
self._run_loop(self.one_loop)
|
||||
self.assertTrue(fut.done())
|
||||
self.assertEqual(fut.result(), [])
|
||||
|
||||
def test_constructor_empty_sequence(self):
|
||||
self._check_empty_sequence([])
|
||||
self._check_empty_sequence(())
|
||||
self._check_empty_sequence(set())
|
||||
self._check_empty_sequence(iter(""))
|
||||
def test_constructor_empty_sequence_use_global_loop(self):
|
||||
# Deprecated in 3.10
|
||||
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.warnings[0].filename, __file__)
|
||||
self.assertIsInstance(fut, asyncio.Future)
|
||||
self.assertIs(fut._loop, self.one_loop)
|
||||
self._run_loop(self.one_loop)
|
||||
self.assertTrue(fut.done())
|
||||
self.assertEqual(fut.result(), [])
|
||||
|
||||
def test_constructor_heterogenous_futures(self):
|
||||
fut1 = self.one_loop.create_future()
|
||||
|
@ -3392,10 +3491,6 @@ def test_result_exception_one_cancellation(self):
|
|||
|
||||
class CoroutineGatherTests(GatherTestsBase, test_utils.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
asyncio.set_event_loop(self.one_loop)
|
||||
|
||||
def wrap_futures(self, *futures):
|
||||
coros = []
|
||||
for fut in futures:
|
||||
|
@ -3404,22 +3499,47 @@ async def coro(fut=fut):
|
|||
coros.append(coro())
|
||||
return coros
|
||||
|
||||
def test_constructor_loop_selection(self):
|
||||
def _gather(self, *args, **kwargs):
|
||||
async def coro():
|
||||
return asyncio.gather(*args, **kwargs)
|
||||
return self.one_loop.run_until_complete(coro())
|
||||
|
||||
def test_constructor_without_loop(self):
|
||||
async def coro():
|
||||
return 'abc'
|
||||
gen1 = 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.warnings[0].filename, __file__)
|
||||
|
||||
def test_constructor_use_running_loop(self):
|
||||
async def coro():
|
||||
return 'abc'
|
||||
gen1 = coro()
|
||||
gen2 = coro()
|
||||
fut = asyncio.gather(gen1, gen2)
|
||||
async def gather():
|
||||
return asyncio.gather(gen1, gen2)
|
||||
fut = self.one_loop.run_until_complete(gather())
|
||||
self.assertIs(fut._loop, self.one_loop)
|
||||
self.one_loop.run_until_complete(fut)
|
||||
|
||||
self.set_event_loop(self.other_loop, cleanup=False)
|
||||
def test_constructor_use_global_loop(self):
|
||||
# Deprecated in 3.10
|
||||
async def coro():
|
||||
return 'abc'
|
||||
asyncio.set_event_loop(self.other_loop)
|
||||
gen3 = coro()
|
||||
gen4 = coro()
|
||||
fut2 = asyncio.gather(gen3, gen4)
|
||||
self.assertIs(fut2._loop, self.other_loop)
|
||||
self.other_loop.run_until_complete(fut2)
|
||||
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.warnings[0].filename, __file__)
|
||||
self.assertIs(fut._loop, self.other_loop)
|
||||
self.other_loop.run_until_complete(fut)
|
||||
|
||||
def test_duplicate_coroutines(self):
|
||||
with self.assertWarns(DeprecationWarning):
|
||||
|
@ -3427,7 +3547,7 @@ def test_duplicate_coroutines(self):
|
|||
def coro(s):
|
||||
return s
|
||||
c = coro('abc')
|
||||
fut = asyncio.gather(c, c, coro('def'), c)
|
||||
fut = self._gather(c, c, coro('def'), c)
|
||||
self._run_loop(self.one_loop)
|
||||
self.assertEqual(fut.result(), ['abc', 'abc', 'def', 'abc'])
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
Deprecated use of :func:`asyncio.get_event_loop` without running event loop.
|
||||
Emit deprecation warning for :mod:`asyncio` functions which implicitly
|
||||
create a :class:`~asyncio.Future` or :class:`~asyncio.Task` objects if there
|
||||
is no running event loop and no explicit *loop* argument is passed:
|
||||
:func:`~asyncio.ensure_future`, :func:`~asyncio.wrap_future`,
|
||||
:func:`~asyncio.gather`, :func:`~asyncio.shield`,
|
||||
:func:`~asyncio.as_completed` and constructors of :class:`~asyncio.Future`,
|
||||
:class:`~asyncio.Task`, :class:`~asyncio.StreamReader`,
|
||||
:class:`~asyncio.StreamReaderProtocol`.
|
|
@ -319,7 +319,7 @@ set_running_loop(PyObject *loop)
|
|||
|
||||
|
||||
static PyObject *
|
||||
get_event_loop(void)
|
||||
get_event_loop(int stacklevel)
|
||||
{
|
||||
PyObject *loop;
|
||||
PyObject *policy;
|
||||
|
@ -331,6 +331,13 @@ get_event_loop(void)
|
|||
return loop;
|
||||
}
|
||||
|
||||
if (PyErr_WarnEx(PyExc_DeprecationWarning,
|
||||
"There is no current event loop",
|
||||
stacklevel))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
policy = PyObject_CallNoArgs(asyncio_get_event_loop_policy);
|
||||
if (policy == NULL) {
|
||||
return NULL;
|
||||
|
@ -489,7 +496,7 @@ future_init(FutureObj *fut, PyObject *loop)
|
|||
fut->fut_blocking = 0;
|
||||
|
||||
if (loop == Py_None) {
|
||||
loop = get_event_loop();
|
||||
loop = get_event_loop(1);
|
||||
if (loop == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -3078,7 +3085,19 @@ static PyObject *
|
|||
_asyncio_get_event_loop_impl(PyObject *module)
|
||||
/*[clinic end generated code: output=2a2d8b2f824c648b input=9364bf2916c8655d]*/
|
||||
{
|
||||
return get_event_loop();
|
||||
return get_event_loop(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]*/
|
||||
{
|
||||
return get_event_loop(stacklevel-1);
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
|
@ -3375,6 +3394,7 @@ 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
|
||||
|
|
41
Modules/clinic/_asynciomodule.c.h
generated
41
Modules/clinic/_asynciomodule.c.h
generated
|
@ -669,6 +669,45 @@ _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)(void(*)(void))_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;
|
||||
static const char * const _keywords[] = {"stacklevel", NULL};
|
||||
static _PyArg_Parser _parser = {NULL, _keywords, "_get_event_loop", 0};
|
||||
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"
|
||||
|
@ -832,4 +871,4 @@ _asyncio__leave_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs,
|
|||
exit:
|
||||
return return_value;
|
||||
}
|
||||
/*[clinic end generated code: output=d0fc522bcbff9d61 input=a9049054013a1b77]*/
|
||||
/*[clinic end generated code: output=0d127162ac92e0c0 input=a9049054013a1b77]*/
|
||||
|
|
Loading…
Reference in a new issue