From 53edb85e6e08765008595a39eb28b4c544baa326 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Mon, 11 May 2015 11:56:36 -0400 Subject: [PATCH] Deprecate async() function in favour of ensure_future() --- asyncio/base_events.py | 2 +- asyncio/tasks.py | 27 +++++++++++++++----- asyncio/windows_events.py | 2 +- tests/test_base_events.py | 6 ++--- tests/test_tasks.py | 48 ++++++++++++++++++++---------------- tests/test_windows_events.py | 2 +- 6 files changed, 54 insertions(+), 33 deletions(-) diff --git a/asyncio/base_events.py b/asyncio/base_events.py index efbb9f4..98aadaf 100644 --- a/asyncio/base_events.py +++ b/asyncio/base_events.py @@ -315,7 +315,7 @@ class BaseEventLoop(events.AbstractEventLoop): self._check_closed() new_task = not isinstance(future, futures.Future) - future = tasks.async(future, loop=self) + future = tasks.ensure_future(future, loop=self) if new_task: # An exception is raised if the future didn't complete, so there # is no need to log the "destroy pending task" message diff --git a/asyncio/tasks.py b/asyncio/tasks.py index 4f19a25..5840d2a 100644 --- a/asyncio/tasks.py +++ b/asyncio/tasks.py @@ -3,7 +3,7 @@ __all__ = ['Task', 'FIRST_COMPLETED', 'FIRST_EXCEPTION', 'ALL_COMPLETED', 'wait', 'wait_for', 'as_completed', 'sleep', 'async', - 'gather', 'shield', + 'gather', 'shield', 'ensure_future', ] import concurrent.futures @@ -12,6 +12,7 @@ import inspect import linecache import sys import traceback +import warnings import weakref from . import coroutines @@ -327,7 +328,7 @@ def wait(fs, *, loop=None, timeout=None, return_when=ALL_COMPLETED): if loop is None: loop = events.get_event_loop() - fs = {async(f, loop=loop) for f in set(fs)} + fs = {ensure_future(f, loop=loop) for f in set(fs)} return (yield from _wait(fs, timeout, return_when, loop)) @@ -361,7 +362,7 @@ def wait_for(fut, timeout, *, loop=None): timeout_handle = loop.call_later(timeout, _release_waiter, waiter) cb = functools.partial(_release_waiter, waiter) - fut = async(fut, loop=loop) + fut = ensure_future(fut, loop=loop) fut.add_done_callback(cb) try: @@ -449,7 +450,7 @@ def as_completed(fs, *, loop=None, timeout=None): if isinstance(fs, futures.Future) or coroutines.iscoroutine(fs): raise TypeError("expect a list of futures, not %s" % type(fs).__name__) loop = loop if loop is not None else events.get_event_loop() - todo = {async(f, loop=loop) for f in set(fs)} + todo = {ensure_future(f, loop=loop) for f in set(fs)} from .queues import Queue # Import here to avoid circular import problem. done = Queue(loop=loop) timeout_handle = None @@ -499,6 +500,20 @@ def sleep(delay, result=None, *, loop=None): def async(coro_or_future, *, loop=None): """Wrap a coroutine in a future. + If the argument is a Future, it is returned directly. + + This function is deprecated in 3.5. Use asyncio.ensure_future() instead. + """ + + warnings.warn("asyncio.async() function is deprecated, use ensure_future()", + RuntimeWarning) + + return ensure_future(coro_or_future, loop=loop) + + +def ensure_future(coro_or_future, *, loop=None): + """Wrap a coroutine in a future. + If the argument is a Future, it is returned directly. """ if isinstance(coro_or_future, futures.Future): @@ -564,7 +579,7 @@ def gather(*coros_or_futures, loop=None, return_exceptions=False): arg_to_fut = {} for arg in set(coros_or_futures): if not isinstance(arg, futures.Future): - fut = async(arg, loop=loop) + fut = ensure_future(arg, loop=loop) if loop is None: loop = fut._loop # The caller cannot control this future, the "destroy pending task" @@ -640,7 +655,7 @@ def shield(arg, *, loop=None): except CancelledError: res = None """ - inner = async(arg, loop=loop) + inner = ensure_future(arg, loop=loop) if inner.done(): # Shortcut. return inner diff --git a/asyncio/windows_events.py b/asyncio/windows_events.py index f311e46..922594f 100644 --- a/asyncio/windows_events.py +++ b/asyncio/windows_events.py @@ -488,7 +488,7 @@ class IocpProactor: future = self._register(ov, listener, finish_accept) coro = accept_coro(future, conn) - tasks.async(coro, loop=self._loop) + tasks.ensure_future(coro, loop=self._loop) return future def connect(self, conn, address): diff --git a/tests/test_base_events.py b/tests/test_base_events.py index fd864ce..8c4498c 100644 --- a/tests/test_base_events.py +++ b/tests/test_base_events.py @@ -504,7 +504,7 @@ class BaseEventLoopTests(test_utils.TestCase): # Test Future.__del__ with mock.patch('asyncio.base_events.logger') as log: - fut = asyncio.async(zero_error_coro(), loop=self.loop) + fut = asyncio.ensure_future(zero_error_coro(), loop=self.loop) fut.add_done_callback(lambda *args: self.loop.stop()) self.loop.run_forever() fut = None # Trigger Future.__del__ or futures._TracebackLogger @@ -703,7 +703,7 @@ class BaseEventLoopTests(test_utils.TestCase): self.set_event_loop(loop) coro = test() - task = asyncio.async(coro, loop=loop) + task = asyncio.ensure_future(coro, loop=loop) self.assertIsInstance(task, MyTask) # make warnings quiet @@ -1265,7 +1265,7 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): "took .* seconds$") # slow task - asyncio.async(stop_loop_coro(self.loop), loop=self.loop) + asyncio.ensure_future(stop_loop_coro(self.loop), loop=self.loop) self.loop.run_forever() fmt, *args = m_logger.warning.call_args[0] self.assertRegex(fmt % tuple(args), diff --git a/tests/test_tasks.py b/tests/test_tasks.py index 5b49e76..8c79983 100644 --- a/tests/test_tasks.py +++ b/tests/test_tasks.py @@ -92,11 +92,11 @@ class TaskTests(test_utils.TestCase): loop.run_until_complete(t) loop.close() - def test_async_coroutine(self): + def test_ensure_future_coroutine(self): @asyncio.coroutine def notmuch(): return 'ok' - t = asyncio.async(notmuch(), loop=self.loop) + t = asyncio.ensure_future(notmuch(), loop=self.loop) self.loop.run_until_complete(t) self.assertTrue(t.done()) self.assertEqual(t.result(), 'ok') @@ -104,16 +104,16 @@ class TaskTests(test_utils.TestCase): loop = asyncio.new_event_loop() self.set_event_loop(loop) - t = asyncio.async(notmuch(), loop=loop) + t = asyncio.ensure_future(notmuch(), loop=loop) self.assertIs(t._loop, loop) loop.run_until_complete(t) loop.close() - def test_async_future(self): + def test_ensure_future_future(self): f_orig = asyncio.Future(loop=self.loop) f_orig.set_result('ko') - f = asyncio.async(f_orig) + f = asyncio.ensure_future(f_orig) self.loop.run_until_complete(f) self.assertTrue(f.done()) self.assertEqual(f.result(), 'ko') @@ -123,19 +123,19 @@ class TaskTests(test_utils.TestCase): self.set_event_loop(loop) with self.assertRaises(ValueError): - f = asyncio.async(f_orig, loop=loop) + f = asyncio.ensure_future(f_orig, loop=loop) loop.close() - f = asyncio.async(f_orig, loop=self.loop) + f = asyncio.ensure_future(f_orig, loop=self.loop) self.assertIs(f, f_orig) - def test_async_task(self): + def test_ensure_future_task(self): @asyncio.coroutine def notmuch(): return 'ok' t_orig = asyncio.Task(notmuch(), loop=self.loop) - t = asyncio.async(t_orig) + t = asyncio.ensure_future(t_orig) self.loop.run_until_complete(t) self.assertTrue(t.done()) self.assertEqual(t.result(), 'ok') @@ -145,16 +145,22 @@ class TaskTests(test_utils.TestCase): self.set_event_loop(loop) with self.assertRaises(ValueError): - t = asyncio.async(t_orig, loop=loop) + t = asyncio.ensure_future(t_orig, loop=loop) loop.close() - t = asyncio.async(t_orig, loop=self.loop) + t = asyncio.ensure_future(t_orig, loop=self.loop) self.assertIs(t, t_orig) - def test_async_neither(self): + def test_ensure_future_neither(self): with self.assertRaises(TypeError): - asyncio.async('ok') + asyncio.ensure_future('ok') + + def test_async_warning(self): + f = asyncio.Future(loop=self.loop) + with self.assertWarnsRegex(RuntimeWarning, + 'function is deprecated, use ensure_'): + self.assertIs(f, asyncio.async(f)) def test_task_repr(self): self.loop.set_debug(False) @@ -1420,7 +1426,7 @@ class TaskTests(test_utils.TestCase): else: proof += 10 - f = asyncio.async(outer(), loop=self.loop) + f = asyncio.ensure_future(outer(), loop=self.loop) test_utils.run_briefly(self.loop) f.cancel() self.loop.run_until_complete(f) @@ -1445,7 +1451,7 @@ class TaskTests(test_utils.TestCase): d, p = yield from asyncio.wait([inner()], loop=self.loop) proof += 100 - f = asyncio.async(outer(), loop=self.loop) + f = asyncio.ensure_future(outer(), loop=self.loop) test_utils.run_briefly(self.loop) f.cancel() self.assertRaises( @@ -1501,7 +1507,7 @@ class TaskTests(test_utils.TestCase): yield from asyncio.shield(inner(), loop=self.loop) proof += 100 - f = asyncio.async(outer(), loop=self.loop) + f = asyncio.ensure_future(outer(), loop=self.loop) test_utils.run_briefly(self.loop) f.cancel() with self.assertRaises(asyncio.CancelledError): @@ -1668,7 +1674,7 @@ class TaskTests(test_utils.TestCase): # schedule the task coro = kill_me(self.loop) - task = asyncio.async(coro, loop=self.loop) + task = asyncio.ensure_future(coro, loop=self.loop) self.assertEqual(asyncio.Task.all_tasks(loop=self.loop), {task}) # execute the task so it waits for future @@ -1996,8 +2002,8 @@ class CoroutineGatherTests(GatherTestsBase, test_utils.TestCase): yield from waiter proof += 1 - child1 = asyncio.async(inner(), loop=self.one_loop) - child2 = asyncio.async(inner(), loop=self.one_loop) + child1 = asyncio.ensure_future(inner(), loop=self.one_loop) + child2 = asyncio.ensure_future(inner(), loop=self.one_loop) gatherer = None @asyncio.coroutine @@ -2007,7 +2013,7 @@ class CoroutineGatherTests(GatherTestsBase, test_utils.TestCase): yield from gatherer proof += 100 - f = asyncio.async(outer(), loop=self.one_loop) + f = asyncio.ensure_future(outer(), loop=self.one_loop) test_utils.run_briefly(self.one_loop) self.assertTrue(f.cancel()) with self.assertRaises(asyncio.CancelledError): @@ -2034,7 +2040,7 @@ class CoroutineGatherTests(GatherTestsBase, test_utils.TestCase): def outer(): yield from asyncio.gather(inner(a), inner(b), loop=self.one_loop) - f = asyncio.async(outer(), loop=self.one_loop) + f = asyncio.ensure_future(outer(), loop=self.one_loop) test_utils.run_briefly(self.one_loop) a.set_result(None) test_utils.run_briefly(self.one_loop) diff --git a/tests/test_windows_events.py b/tests/test_windows_events.py index 73d8fcd..657a427 100644 --- a/tests/test_windows_events.py +++ b/tests/test_windows_events.py @@ -37,7 +37,7 @@ class ProactorTests(test_utils.TestCase): def test_close(self): a, b = self.loop._socketpair() trans = self.loop._make_socket_transport(a, asyncio.Protocol()) - f = asyncio.async(self.loop.sock_recv(b, 100)) + f = asyncio.ensure_future(self.loop.sock_recv(b, 100)) trans.close() self.loop.run_until_complete(f) self.assertEqual(f.result(), b'')