bpo-36921: Deprecate @coroutine for sake of async def (GH-13346)

The second attempt. Now deprecate `@coroutine` only, keep `yield from fut` as is.


https://bugs.python.org/issue36921
This commit is contained in:
Andrew Svetlov 2019-05-16 17:52:10 +03:00 committed by Miss Islington (bot)
parent dbacfc2273
commit 68b34a7204
12 changed files with 311 additions and 320 deletions

View File

@ -916,12 +916,13 @@ enforced.
async def main(): async def main():
await old_style_coroutine() await old_style_coroutine()
This decorator is **deprecated** and is scheduled for removal in
Python 3.10.
This decorator should not be used for :keyword:`async def` This decorator should not be used for :keyword:`async def`
coroutines. coroutines.
.. deprecated-removed:: 3.8 3.10
Use :keyword:`async def` instead.
.. function:: iscoroutine(obj) .. function:: iscoroutine(obj)
Return ``True`` if *obj* is a :ref:`coroutine object <coroutine>`. Return ``True`` if *obj* is a :ref:`coroutine object <coroutine>`.

View File

@ -7,6 +7,7 @@ import os
import sys import sys
import traceback import traceback
import types import types
import warnings
from . import base_futures from . import base_futures
from . import constants from . import constants
@ -107,6 +108,9 @@ def coroutine(func):
If the coroutine is not yielded from before it is destroyed, If the coroutine is not yielded from before it is destroyed,
an error message is logged. an error message is logged.
""" """
warnings.warn('"@coroutine" decorator is deprecated since Python 3.8, use "async def" instead',
DeprecationWarning,
stacklevel=2)
if inspect.iscoroutinefunction(func): if inspect.iscoroutinefunction(func):
# In Python 3.5 that's all we need to do for coroutines # In Python 3.5 that's all we need to do for coroutines
# defined with "async def". # defined with "async def".

View File

@ -3,12 +3,13 @@
__all__ = ('Lock', 'Event', 'Condition', 'Semaphore', 'BoundedSemaphore') __all__ = ('Lock', 'Event', 'Condition', 'Semaphore', 'BoundedSemaphore')
import collections import collections
import types
import warnings import warnings
from . import events from . import events
from . import futures from . import futures
from . import exceptions from . import exceptions
from .coroutines import coroutine from .import coroutines
class _ContextManager: class _ContextManager:
@ -55,7 +56,7 @@ class _ContextManagerMixin:
# always raises; that's how the with-statement works. # always raises; that's how the with-statement works.
pass pass
@coroutine @types.coroutine
def __iter__(self): def __iter__(self):
# This is not a coroutine. It is meant to enable the idiom: # This is not a coroutine. It is meant to enable the idiom:
# #
@ -78,6 +79,9 @@ class _ContextManagerMixin:
yield from self.acquire() yield from self.acquire()
return _ContextManager(self) return _ContextManager(self)
# The flag is needed for legacy asyncio.iscoroutine()
__iter__._is_coroutine = coroutines._is_coroutine
async def __acquire_ctx(self): async def __acquire_ctx(self):
await self.acquire() await self.acquire()
return _ContextManager(self) return _ContextManager(self)

View File

@ -23,7 +23,7 @@ from . import coroutines
from . import events from . import events
from . import exceptions from . import exceptions
from . import futures from . import futures
from .coroutines import coroutine from .coroutines import _is_coroutine
# Helper to generate new task names # Helper to generate new task names
# This uses itertools.count() instead of a "+= 1" operation because the latter # This uses itertools.count() instead of a "+= 1" operation because the latter
@ -638,7 +638,7 @@ def ensure_future(coro_or_future, *, loop=None):
'required') 'required')
@coroutine @types.coroutine
def _wrap_awaitable(awaitable): def _wrap_awaitable(awaitable):
"""Helper for asyncio.ensure_future(). """Helper for asyncio.ensure_future().
@ -647,6 +647,8 @@ def _wrap_awaitable(awaitable):
""" """
return (yield from awaitable.__await__()) return (yield from awaitable.__await__())
_wrap_awaitable._is_coroutine = _is_coroutine
class _GatheringFuture(futures.Future): class _GatheringFuture(futures.Future):
"""Helper for gather(). """Helper for gather().

View File

@ -575,9 +575,8 @@ class BaseEventLoopTests(test_utils.TestCase):
def test_default_exc_handler_coro(self): def test_default_exc_handler_coro(self):
self.loop._process_events = mock.Mock() self.loop._process_events = mock.Mock()
@asyncio.coroutine async def zero_error_coro():
def zero_error_coro(): await asyncio.sleep(0.01)
yield from asyncio.sleep(0.01)
1/0 1/0
# Test Future.__del__ # Test Future.__del__
@ -723,8 +722,7 @@ class BaseEventLoopTests(test_utils.TestCase):
class MyTask(asyncio.Task): class MyTask(asyncio.Task):
pass pass
@asyncio.coroutine async def coro():
def coro():
pass pass
factory = lambda loop, coro: MyTask(coro, loop=loop) factory = lambda loop, coro: MyTask(coro, loop=loop)
@ -779,8 +777,7 @@ class BaseEventLoopTests(test_utils.TestCase):
class MyTask(asyncio.Task): class MyTask(asyncio.Task):
pass pass
@asyncio.coroutine async def test():
def test():
pass pass
class EventLoop(base_events.BaseEventLoop): class EventLoop(base_events.BaseEventLoop):
@ -830,8 +827,7 @@ class BaseEventLoopTests(test_utils.TestCase):
# Python issue #22601: ensure that the temporary task created by # Python issue #22601: ensure that the temporary task created by
# run_forever() consumes the KeyboardInterrupt and so don't log # run_forever() consumes the KeyboardInterrupt and so don't log
# a warning # a warning
@asyncio.coroutine async def raise_keyboard_interrupt():
def raise_keyboard_interrupt():
raise KeyboardInterrupt raise KeyboardInterrupt
self.loop._process_events = mock.Mock() self.loop._process_events = mock.Mock()
@ -849,8 +845,7 @@ class BaseEventLoopTests(test_utils.TestCase):
def test_run_until_complete_baseexception(self): def test_run_until_complete_baseexception(self):
# Python issue #22429: run_until_complete() must not schedule a pending # Python issue #22429: run_until_complete() must not schedule a pending
# call to stop() if the future raised a BaseException # call to stop() if the future raised a BaseException
@asyncio.coroutine async def raise_keyboard_interrupt():
def raise_keyboard_interrupt():
raise KeyboardInterrupt raise KeyboardInterrupt
self.loop._process_events = mock.Mock() self.loop._process_events = mock.Mock()
@ -1070,9 +1065,7 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
class MyProto(asyncio.Protocol): class MyProto(asyncio.Protocol):
pass pass
@asyncio.coroutine async def getaddrinfo(*args, **kw):
def getaddrinfo(*args, **kw):
yield from []
return [(2, 1, 6, '', ('107.6.106.82', 80)), return [(2, 1, 6, '', ('107.6.106.82', 80)),
(2, 1, 6, '', ('107.6.106.82', 80))] (2, 1, 6, '', ('107.6.106.82', 80))]
@ -1191,9 +1184,8 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
self.assertRaises(ValueError, self.loop.run_until_complete, coro) self.assertRaises(ValueError, self.loop.run_until_complete, coro)
def test_create_connection_no_getaddrinfo(self): def test_create_connection_no_getaddrinfo(self):
@asyncio.coroutine async def getaddrinfo(*args, **kw):
def getaddrinfo(*args, **kw): return []
yield from []
def getaddrinfo_task(*args, **kwds): def getaddrinfo_task(*args, **kwds):
return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop) return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop)
@ -1219,8 +1211,7 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
OSError, self.loop.run_until_complete, coro) OSError, self.loop.run_until_complete, coro)
def test_create_connection_multiple(self): def test_create_connection_multiple(self):
@asyncio.coroutine async def getaddrinfo(*args, **kw):
def getaddrinfo(*args, **kw):
return [(2, 1, 6, '', ('0.0.0.1', 80)), return [(2, 1, 6, '', ('0.0.0.1', 80)),
(2, 1, 6, '', ('0.0.0.2', 80))] (2, 1, 6, '', ('0.0.0.2', 80))]
@ -1247,8 +1238,7 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
m_socket.socket.return_value.bind = bind m_socket.socket.return_value.bind = bind
@asyncio.coroutine async def getaddrinfo(*args, **kw):
def getaddrinfo(*args, **kw):
return [(2, 1, 6, '', ('0.0.0.1', 80)), return [(2, 1, 6, '', ('0.0.0.1', 80)),
(2, 1, 6, '', ('0.0.0.2', 80))] (2, 1, 6, '', ('0.0.0.2', 80))]
@ -1349,8 +1339,7 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
self.loop.run_until_complete(coro) self.loop.run_until_complete(coro)
def test_create_connection_no_local_addr(self): def test_create_connection_no_local_addr(self):
@asyncio.coroutine async def getaddrinfo(host, *args, **kw):
def getaddrinfo(host, *args, **kw):
if host == 'example.com': if host == 'example.com':
return [(2, 1, 6, '', ('107.6.106.82', 80)), return [(2, 1, 6, '', ('107.6.106.82', 80)),
(2, 1, 6, '', ('107.6.106.82', 80))] (2, 1, 6, '', ('107.6.106.82', 80))]
@ -1488,11 +1477,10 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
# if host is empty string use None instead # if host is empty string use None instead
host = object() host = object()
@asyncio.coroutine async def getaddrinfo(*args, **kw):
def getaddrinfo(*args, **kw):
nonlocal host nonlocal host
host = args[0] host = args[0]
yield from [] return []
def getaddrinfo_task(*args, **kwds): def getaddrinfo_task(*args, **kwds):
return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop) return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop)
@ -1854,9 +1842,10 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
MyProto, sock, None, None, mock.ANY, mock.ANY) MyProto, sock, None, None, mock.ANY, mock.ANY)
def test_call_coroutine(self): def test_call_coroutine(self):
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def simple_coroutine(): @asyncio.coroutine
pass def simple_coroutine():
pass
self.loop.set_debug(True) self.loop.set_debug(True)
coro_func = simple_coroutine coro_func = simple_coroutine
@ -1880,9 +1869,7 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
def stop_loop_cb(loop): def stop_loop_cb(loop):
loop.stop() loop.stop()
@asyncio.coroutine async def stop_loop_coro(loop):
def stop_loop_coro(loop):
yield from ()
loop.stop() loop.stop()
asyncio.set_event_loop(self.loop) asyncio.set_event_loop(self.loop)
@ -1909,8 +1896,7 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
class RunningLoopTests(unittest.TestCase): class RunningLoopTests(unittest.TestCase):
def test_running_loop_within_a_loop(self): def test_running_loop_within_a_loop(self):
@asyncio.coroutine async def runner(loop):
def runner(loop):
loop.run_forever() loop.run_forever()
loop = asyncio.new_event_loop() loop = asyncio.new_event_loop()

View File

@ -253,12 +253,10 @@ class EventLoopTestsMixin:
super().tearDown() super().tearDown()
def test_run_until_complete_nesting(self): def test_run_until_complete_nesting(self):
@asyncio.coroutine async def coro1():
def coro1(): await asyncio.sleep(0)
yield
@asyncio.coroutine async def coro2():
def coro2():
self.assertTrue(self.loop.is_running()) self.assertTrue(self.loop.is_running())
self.loop.run_until_complete(coro1()) self.loop.run_until_complete(coro1())
@ -735,8 +733,7 @@ class EventLoopTestsMixin:
@mock.patch('asyncio.base_events.socket') @mock.patch('asyncio.base_events.socket')
def create_server_multiple_hosts(self, family, hosts, mock_sock): def create_server_multiple_hosts(self, family, hosts, mock_sock):
@asyncio.coroutine async def getaddrinfo(host, port, *args, **kw):
def getaddrinfo(host, port, *args, **kw):
if family == socket.AF_INET: if family == socket.AF_INET:
return [(family, socket.SOCK_STREAM, 6, '', (host, port))] return [(family, socket.SOCK_STREAM, 6, '', (host, port))]
else: else:
@ -1662,8 +1659,7 @@ class EventLoopTestsMixin:
loop.add_writer(w, callback) loop.add_writer(w, callback)
def test_close_running_event_loop(self): def test_close_running_event_loop(self):
@asyncio.coroutine async def close_loop(loop):
def close_loop(loop):
self.loop.close() self.loop.close()
coro = close_loop(self.loop) coro = close_loop(self.loop)
@ -1673,8 +1669,7 @@ class EventLoopTestsMixin:
def test_close(self): def test_close(self):
self.loop.close() self.loop.close()
@asyncio.coroutine async def test():
def test():
pass pass
func = lambda: False func = lambda: False
@ -2142,7 +2137,8 @@ class HandleTests(test_utils.TestCase):
'<Handle cancelled>') '<Handle cancelled>')
# decorated function # decorated function
cb = asyncio.coroutine(noop) with self.assertWarns(DeprecationWarning):
cb = asyncio.coroutine(noop)
h = asyncio.Handle(cb, (), self.loop) h = asyncio.Handle(cb, (), self.loop)
self.assertEqual(repr(h), self.assertEqual(repr(h),
'<Handle noop() at %s:%s>' '<Handle noop() at %s:%s>'

View File

@ -44,10 +44,11 @@ class LockTests(test_utils.TestCase):
self.assertTrue(repr(lock).endswith('[unlocked]>')) self.assertTrue(repr(lock).endswith('[unlocked]>'))
self.assertTrue(RGX_REPR.match(repr(lock))) self.assertTrue(RGX_REPR.match(repr(lock)))
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def acquire_lock(): @asyncio.coroutine
with self.assertWarns(DeprecationWarning): def acquire_lock():
yield from lock with self.assertWarns(DeprecationWarning):
yield from lock
self.loop.run_until_complete(acquire_lock()) self.loop.run_until_complete(acquire_lock())
self.assertTrue(repr(lock).endswith('[locked]>')) self.assertTrue(repr(lock).endswith('[locked]>'))
@ -56,10 +57,11 @@ class LockTests(test_utils.TestCase):
def test_lock(self): def test_lock(self):
lock = asyncio.Lock(loop=self.loop) lock = asyncio.Lock(loop=self.loop)
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def acquire_lock(): @asyncio.coroutine
with self.assertWarns(DeprecationWarning): def acquire_lock():
return (yield from lock) with self.assertWarns(DeprecationWarning):
return (yield from lock)
res = self.loop.run_until_complete(acquire_lock()) res = self.loop.run_until_complete(acquire_lock())
@ -79,17 +81,18 @@ class LockTests(test_utils.TestCase):
asyncio.BoundedSemaphore(loop=loop), asyncio.BoundedSemaphore(loop=loop),
] ]
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def test(lock): @asyncio.coroutine
yield from asyncio.sleep(0.01) def test(lock):
self.assertFalse(lock.locked()) yield from asyncio.sleep(0.01)
with self.assertWarns(DeprecationWarning):
with (yield from lock) as _lock:
self.assertIs(_lock, None)
self.assertTrue(lock.locked())
yield from asyncio.sleep(0.01)
self.assertTrue(lock.locked())
self.assertFalse(lock.locked()) self.assertFalse(lock.locked())
with self.assertWarns(DeprecationWarning):
with (yield from lock) as _lock:
self.assertIs(_lock, None)
self.assertTrue(lock.locked())
yield from asyncio.sleep(0.01)
self.assertTrue(lock.locked())
self.assertFalse(lock.locked())
for primitive in primitives: for primitive in primitives:
loop.run_until_complete(test(primitive)) loop.run_until_complete(test(primitive))
@ -290,10 +293,11 @@ class LockTests(test_utils.TestCase):
def test_context_manager(self): def test_context_manager(self):
lock = asyncio.Lock(loop=self.loop) lock = asyncio.Lock(loop=self.loop)
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def acquire_lock(): @asyncio.coroutine
with self.assertWarns(DeprecationWarning): def acquire_lock():
return (yield from lock) with self.assertWarns(DeprecationWarning):
return (yield from lock)
with self.loop.run_until_complete(acquire_lock()): with self.loop.run_until_complete(acquire_lock()):
self.assertTrue(lock.locked()) self.assertTrue(lock.locked())
@ -303,10 +307,11 @@ class LockTests(test_utils.TestCase):
def test_context_manager_cant_reuse(self): def test_context_manager_cant_reuse(self):
lock = asyncio.Lock(loop=self.loop) lock = asyncio.Lock(loop=self.loop)
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def acquire_lock(): @asyncio.coroutine
with self.assertWarns(DeprecationWarning): def acquire_lock():
return (yield from lock) with self.assertWarns(DeprecationWarning):
return (yield from lock)
# This spells "yield from lock" outside a generator. # This spells "yield from lock" outside a generator.
cm = self.loop.run_until_complete(acquire_lock()) cm = self.loop.run_until_complete(acquire_lock())
@ -773,10 +778,11 @@ class ConditionTests(test_utils.TestCase):
def test_context_manager(self): def test_context_manager(self):
cond = asyncio.Condition(loop=self.loop) cond = asyncio.Condition(loop=self.loop)
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def acquire_cond(): @asyncio.coroutine
with self.assertWarns(DeprecationWarning): def acquire_cond():
return (yield from cond) with self.assertWarns(DeprecationWarning):
return (yield from cond)
with self.loop.run_until_complete(acquire_cond()): with self.loop.run_until_complete(acquire_cond()):
self.assertTrue(cond.locked()) self.assertTrue(cond.locked())
@ -869,10 +875,11 @@ class SemaphoreTests(test_utils.TestCase):
sem = asyncio.Semaphore(loop=self.loop) sem = asyncio.Semaphore(loop=self.loop)
self.assertEqual(1, sem._value) self.assertEqual(1, sem._value)
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def acquire_lock(): @asyncio.coroutine
with self.assertWarns(DeprecationWarning): def acquire_lock():
return (yield from sem) with self.assertWarns(DeprecationWarning):
return (yield from sem)
res = self.loop.run_until_complete(acquire_lock()) res = self.loop.run_until_complete(acquire_lock())
@ -1012,10 +1019,11 @@ class SemaphoreTests(test_utils.TestCase):
def test_context_manager(self): def test_context_manager(self):
sem = asyncio.Semaphore(2, loop=self.loop) sem = asyncio.Semaphore(2, loop=self.loop)
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def acquire_lock(): @asyncio.coroutine
with self.assertWarns(DeprecationWarning): def acquire_lock():
return (yield from sem) with self.assertWarns(DeprecationWarning):
return (yield from sem)
with self.loop.run_until_complete(acquire_lock()): with self.loop.run_until_complete(acquire_lock()):
self.assertFalse(sem.locked()) self.assertFalse(sem.locked())

View File

@ -130,9 +130,10 @@ class CoroutineTests(BaseTest):
def __await__(self): def __await__(self):
return ('spam',) return ('spam',)
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def func(): @asyncio.coroutine
return Awaitable() def func():
return Awaitable()
coro = func() coro = func()
self.assertEqual(coro.send(None), 'spam') self.assertEqual(coro.send(None), 'spam')

View File

@ -588,8 +588,7 @@ class StreamTests(test_utils.TestCase):
stream = asyncio.StreamReader(loop=self.loop, stream = asyncio.StreamReader(loop=self.loop,
_asyncio_internal=True) _asyncio_internal=True)
@asyncio.coroutine async def set_err():
def set_err():
stream.set_exception(ValueError()) stream.set_exception(ValueError())
t1 = asyncio.Task(stream.readline(), loop=self.loop) t1 = asyncio.Task(stream.readline(), loop=self.loop)

View File

@ -28,8 +28,7 @@ def tearDownModule():
asyncio.set_event_loop_policy(None) asyncio.set_event_loop_policy(None)
@asyncio.coroutine async def coroutine_function():
def coroutine_function():
pass pass
@ -103,8 +102,7 @@ class BaseTaskTests:
def __del__(self): def __del__(self):
gc.collect() gc.collect()
@asyncio.coroutine async def run():
def run():
return Evil() return Evil()
self.loop.run_until_complete( self.loop.run_until_complete(
@ -138,8 +136,7 @@ class BaseTaskTests:
self.loop.run_until_complete(task) self.loop.run_until_complete(task)
def test_task_class(self): def test_task_class(self):
@asyncio.coroutine async def notmuch():
def notmuch():
return 'ok' return 'ok'
t = self.new_task(self.loop, notmuch()) t = self.new_task(self.loop, notmuch())
self.loop.run_until_complete(t) self.loop.run_until_complete(t)
@ -156,9 +153,10 @@ class BaseTaskTests:
loop.close() loop.close()
def test_ensure_future_coroutine(self): def test_ensure_future_coroutine(self):
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def notmuch(): @asyncio.coroutine
return 'ok' def notmuch():
return 'ok'
t = asyncio.ensure_future(notmuch(), loop=self.loop) t = asyncio.ensure_future(notmuch(), loop=self.loop)
self.loop.run_until_complete(t) self.loop.run_until_complete(t)
self.assertTrue(t.done()) self.assertTrue(t.done())
@ -194,8 +192,7 @@ class BaseTaskTests:
self.assertIs(f, f_orig) self.assertIs(f, f_orig)
def test_ensure_future_task(self): def test_ensure_future_task(self):
@asyncio.coroutine async def notmuch():
def notmuch():
return 'ok' return 'ok'
t_orig = self.new_task(self.loop, notmuch()) t_orig = self.new_task(self.loop, notmuch())
t = asyncio.ensure_future(t_orig) t = asyncio.ensure_future(t_orig)
@ -222,9 +219,10 @@ class BaseTaskTests:
def __await__(self): def __await__(self):
return (yield from self.coro) return (yield from self.coro)
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def coro(): @asyncio.coroutine
return 'ok' def coro():
return 'ok'
loop = asyncio.new_event_loop() loop = asyncio.new_event_loop()
self.set_event_loop(loop) self.set_event_loop(loop)
@ -276,9 +274,7 @@ class BaseTaskTests:
def test_task_repr(self): def test_task_repr(self):
self.loop.set_debug(False) self.loop.set_debug(False)
@asyncio.coroutine async def notmuch():
def notmuch():
yield from []
return 'abc' return 'abc'
# test coroutine function # test coroutine function
@ -327,8 +323,7 @@ class BaseTaskTests:
"<Task finished name='TestTask' %s result='abc'>" % coro) "<Task finished name='TestTask' %s result='abc'>" % coro)
def test_task_repr_autogenerated(self): def test_task_repr_autogenerated(self):
@asyncio.coroutine async def notmuch():
def notmuch():
return 123 return 123
t1 = self.new_task(self.loop, notmuch(), None) t1 = self.new_task(self.loop, notmuch(), None)
@ -346,8 +341,7 @@ class BaseTaskTests:
self.loop.run_until_complete(t2) self.loop.run_until_complete(t2)
def test_task_repr_name_not_str(self): def test_task_repr_name_not_str(self):
@asyncio.coroutine async def notmuch():
def notmuch():
return 123 return 123
t = self.new_task(self.loop, notmuch()) t = self.new_task(self.loop, notmuch())
@ -358,11 +352,12 @@ class BaseTaskTests:
def test_task_repr_coro_decorator(self): def test_task_repr_coro_decorator(self):
self.loop.set_debug(False) self.loop.set_debug(False)
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def notmuch(): @asyncio.coroutine
# notmuch() function doesn't use yield from: it will be wrapped by def notmuch():
# @coroutine decorator # notmuch() function doesn't use yield from: it will be wrapped by
return 123 # @coroutine decorator
return 123
# test coroutine function # test coroutine function
self.assertEqual(notmuch.__name__, 'notmuch') self.assertEqual(notmuch.__name__, 'notmuch')
@ -440,7 +435,8 @@ class BaseTaskTests:
async def func(x, y): async def func(x, y):
await asyncio.sleep(0) await asyncio.sleep(0)
partial_func = asyncio.coroutine(functools.partial(func, 1)) with self.assertWarns(DeprecationWarning):
partial_func = asyncio.coroutine(functools.partial(func, 1))
task = self.loop.create_task(partial_func(2)) task = self.loop.create_task(partial_func(2))
# make warnings quiet # make warnings quiet
@ -492,11 +488,12 @@ class BaseTaskTests:
self.assertFalse(t.cancel()) self.assertFalse(t.cancel())
def test_cancel_yield(self): def test_cancel_yield(self):
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def task(): @asyncio.coroutine
yield def task():
yield yield
return 12 yield
return 12
t = self.new_task(self.loop, task()) t = self.new_task(self.loop, task())
test_utils.run_briefly(self.loop) # start coro test_utils.run_briefly(self.loop) # start coro
@ -618,8 +615,7 @@ class BaseTaskTests:
loop = asyncio.new_event_loop() loop = asyncio.new_event_loop()
self.set_event_loop(loop) self.set_event_loop(loop)
@asyncio.coroutine async def task():
def task():
t.cancel() t.cancel()
self.assertTrue(t._must_cancel) # White-box test. self.assertTrue(t._must_cancel) # White-box test.
return 12 return 12
@ -736,8 +732,7 @@ class BaseTaskTests:
foo_started = False foo_started = False
@asyncio.coroutine async def foo():
def foo():
nonlocal foo_started nonlocal foo_started
foo_started = True foo_started = True
@ -814,8 +809,7 @@ class BaseTaskTests:
def test_wait_for_blocking(self): def test_wait_for_blocking(self):
loop = self.new_test_loop() loop = self.new_test_loop()
@asyncio.coroutine async def coro():
def coro():
return 'done' return 'done'
res = loop.run_until_complete(asyncio.wait_for(coro(), timeout=None)) res = loop.run_until_complete(asyncio.wait_for(coro(), timeout=None))
@ -976,9 +970,10 @@ class BaseTaskTests:
def test_wait_duplicate_coroutines(self): def test_wait_duplicate_coroutines(self):
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def coro(s): @asyncio.coroutine
return s def coro(s):
return s
c = coro('test') c = coro('test')
task =self.new_task( task =self.new_task(
@ -1036,14 +1031,12 @@ class BaseTaskTests:
# there is possibility that some tasks in the pending list # there is possibility that some tasks in the pending list
# became done but their callbacks haven't all been called yet # became done but their callbacks haven't all been called yet
@asyncio.coroutine async def coro1():
def coro1(): await asyncio.sleep(0)
yield
@asyncio.coroutine async def coro2():
def coro2(): await asyncio.sleep(0)
yield await asyncio.sleep(0)
yield
a = self.new_task(self.loop, coro1()) a = self.new_task(self.loop, coro1())
b = self.new_task(self.loop, coro2()) b = self.new_task(self.loop, coro2())
@ -1070,8 +1063,7 @@ class BaseTaskTests:
# first_exception, task already has exception # first_exception, task already has exception
a = self.new_task(loop, asyncio.sleep(10.0)) a = self.new_task(loop, asyncio.sleep(10.0))
@asyncio.coroutine async def exc():
def exc():
raise ZeroDivisionError('err') raise ZeroDivisionError('err')
b = self.new_task(loop, exc()) b = self.new_task(loop, exc())
@ -1131,9 +1123,8 @@ class BaseTaskTests:
a = self.new_task(loop, asyncio.sleep(0.1)) a = self.new_task(loop, asyncio.sleep(0.1))
@asyncio.coroutine async def sleeper():
def sleeper(): await asyncio.sleep(0.15)
yield from asyncio.sleep(0.15)
raise ZeroDivisionError('really') raise ZeroDivisionError('really')
b = self.new_task(loop, sleeper()) b = self.new_task(loop, sleeper())
@ -1220,25 +1211,25 @@ class BaseTaskTests:
completed = set() completed = set()
time_shifted = False time_shifted = False
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def sleeper(dt, x): @asyncio.coroutine
nonlocal time_shifted def sleeper(dt, x):
yield from asyncio.sleep(dt) nonlocal time_shifted
completed.add(x) yield from asyncio.sleep(dt)
if not time_shifted and 'a' in completed and 'b' in completed: completed.add(x)
time_shifted = True if not time_shifted and 'a' in completed and 'b' in completed:
loop.advance_time(0.14) time_shifted = True
return x loop.advance_time(0.14)
return x
a = sleeper(0.01, 'a') a = sleeper(0.01, 'a')
b = sleeper(0.01, 'b') b = sleeper(0.01, 'b')
c = sleeper(0.15, 'c') c = sleeper(0.15, 'c')
@asyncio.coroutine async def foo():
def foo():
values = [] values = []
for f in asyncio.as_completed([b, c, a], loop=loop): for f in asyncio.as_completed([b, c, a], loop=loop):
values.append((yield from f)) values.append(await f)
return values return values
res = loop.run_until_complete(self.new_task(loop, foo())) res = loop.run_until_complete(self.new_task(loop, foo()))
@ -1350,18 +1341,20 @@ class BaseTaskTests:
def test_as_completed_duplicate_coroutines(self): def test_as_completed_duplicate_coroutines(self):
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def coro(s): @asyncio.coroutine
return s def coro(s):
return s
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def runner(): @asyncio.coroutine
result = [] def runner():
c = coro('ham') result = []
for f in asyncio.as_completed([c, c, coro('spam')], c = coro('ham')
loop=self.loop): for f in asyncio.as_completed([c, c, coro('spam')],
result.append((yield from f)) loop=self.loop):
return result result.append((yield from f))
return result
fut = self.new_task(self.loop, runner()) fut = self.new_task(self.loop, runner())
self.loop.run_until_complete(fut) self.loop.run_until_complete(fut)
@ -1380,10 +1373,9 @@ class BaseTaskTests:
loop = self.new_test_loop(gen) loop = self.new_test_loop(gen)
@asyncio.coroutine async def sleeper(dt, arg):
def sleeper(dt, arg): await asyncio.sleep(dt/2)
yield from asyncio.sleep(dt/2) res = await asyncio.sleep(dt/2, arg)
res = yield from asyncio.sleep(dt/2, arg)
return res return res
t = self.new_task(loop, sleeper(0.1, 'yeah')) t = self.new_task(loop, sleeper(0.1, 'yeah'))
@ -1431,16 +1423,14 @@ class BaseTaskTests:
loop = self.new_test_loop(gen) loop = self.new_test_loop(gen)
@asyncio.coroutine async def sleep(dt):
def sleep(dt): await asyncio.sleep(dt)
yield from asyncio.sleep(dt)
@asyncio.coroutine async def doit():
def doit():
sleeper = self.new_task(loop, sleep(5000)) sleeper = self.new_task(loop, sleep(5000))
loop.call_later(0.1, sleeper.cancel) loop.call_later(0.1, sleeper.cancel)
try: try:
yield from sleeper await sleeper
except asyncio.CancelledError: except asyncio.CancelledError:
return 'cancelled' return 'cancelled'
else: else:
@ -1453,9 +1443,8 @@ class BaseTaskTests:
def test_task_cancel_waiter_future(self): def test_task_cancel_waiter_future(self):
fut = self.new_future(self.loop) fut = self.new_future(self.loop)
@asyncio.coroutine async def coro():
def coro(): await fut
yield from fut
task = self.new_task(self.loop, coro()) task = self.new_task(self.loop, coro())
test_utils.run_briefly(self.loop) test_utils.run_briefly(self.loop)
@ -1469,8 +1458,7 @@ class BaseTaskTests:
self.assertTrue(fut.cancelled()) self.assertTrue(fut.cancelled())
def test_task_set_methods(self): def test_task_set_methods(self):
@asyncio.coroutine async def notmuch():
def notmuch():
return 'ko' return 'ko'
gen = notmuch() gen = notmuch()
@ -1487,11 +1475,12 @@ class BaseTaskTests:
'ko') 'ko')
def test_step_result(self): def test_step_result(self):
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def notmuch(): @asyncio.coroutine
yield None def notmuch():
yield 1 yield None
return 'ko' yield 1
return 'ko'
self.assertRaises( self.assertRaises(
RuntimeError, self.loop.run_until_complete, notmuch()) RuntimeError, self.loop.run_until_complete, notmuch())
@ -1511,10 +1500,9 @@ class BaseTaskTests:
fut = Fut(loop=self.loop) fut = Fut(loop=self.loop)
result = None result = None
@asyncio.coroutine async def wait_for_future():
def wait_for_future():
nonlocal result nonlocal result
result = yield from fut result = await fut
t = self.new_task(self.loop, wait_for_future()) t = self.new_task(self.loop, wait_for_future())
test_utils.run_briefly(self.loop) test_utils.run_briefly(self.loop)
@ -1536,16 +1524,14 @@ class BaseTaskTests:
loop = self.new_test_loop(gen) loop = self.new_test_loop(gen)
@asyncio.coroutine async def sleeper():
def sleeper(): await asyncio.sleep(10)
yield from asyncio.sleep(10)
base_exc = BaseException() base_exc = BaseException()
@asyncio.coroutine async def notmutch():
def notmutch():
try: try:
yield from sleeper() await sleeper()
except asyncio.CancelledError: except asyncio.CancelledError:
raise base_exc raise base_exc
@ -1571,9 +1557,10 @@ class BaseTaskTests:
yield yield
self.assertFalse(asyncio.iscoroutinefunction(fn1)) self.assertFalse(asyncio.iscoroutinefunction(fn1))
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def fn2(): @asyncio.coroutine
yield def fn2():
yield
self.assertTrue(asyncio.iscoroutinefunction(fn2)) self.assertTrue(asyncio.iscoroutinefunction(fn2))
self.assertFalse(asyncio.iscoroutinefunction(mock.Mock())) self.assertFalse(asyncio.iscoroutinefunction(mock.Mock()))
@ -1581,9 +1568,10 @@ class BaseTaskTests:
def test_yield_vs_yield_from(self): def test_yield_vs_yield_from(self):
fut = self.new_future(self.loop) fut = self.new_future(self.loop)
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def wait_for_future(): @asyncio.coroutine
yield fut def wait_for_future():
yield fut
task = wait_for_future() task = wait_for_future()
with self.assertRaises(RuntimeError): with self.assertRaises(RuntimeError):
@ -1592,17 +1580,19 @@ class BaseTaskTests:
self.assertFalse(fut.done()) self.assertFalse(fut.done())
def test_yield_vs_yield_from_generator(self): def test_yield_vs_yield_from_generator(self):
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def coro(): @asyncio.coroutine
yield def coro():
yield
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def wait_for_future(): @asyncio.coroutine
gen = coro() def wait_for_future():
try: gen = coro()
yield gen try:
finally: yield gen
gen.close() finally:
gen.close()
task = wait_for_future() task = wait_for_future()
self.assertRaises( self.assertRaises(
@ -1610,9 +1600,10 @@ class BaseTaskTests:
self.loop.run_until_complete, task) self.loop.run_until_complete, task)
def test_coroutine_non_gen_function(self): def test_coroutine_non_gen_function(self):
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def func(): @asyncio.coroutine
return 'test' def func():
return 'test'
self.assertTrue(asyncio.iscoroutinefunction(func)) self.assertTrue(asyncio.iscoroutinefunction(func))
@ -1625,12 +1616,12 @@ class BaseTaskTests:
def test_coroutine_non_gen_function_return_future(self): def test_coroutine_non_gen_function_return_future(self):
fut = self.new_future(self.loop) fut = self.new_future(self.loop)
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def func(): @asyncio.coroutine
return fut def func():
return fut
@asyncio.coroutine async def coro():
def coro():
fut.set_result('test') fut.set_result('test')
t1 = self.new_task(self.loop, func()) t1 = self.new_task(self.loop, func())
@ -1887,11 +1878,12 @@ class BaseTaskTests:
# A function that asserts various things. # A function that asserts various things.
# Called twice, with different debug flag values. # Called twice, with different debug flag values.
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def coro(): @asyncio.coroutine
# The actual coroutine. def coro():
self.assertTrue(gen.gi_running) # The actual coroutine.
yield from fut self.assertTrue(gen.gi_running)
yield from fut
# A completed Future used to run the coroutine. # A completed Future used to run the coroutine.
fut = self.new_future(self.loop) fut = self.new_future(self.loop)
@ -1922,19 +1914,22 @@ class BaseTaskTests:
def test_yield_from_corowrapper(self): def test_yield_from_corowrapper(self):
with set_coroutine_debug(True): with set_coroutine_debug(True):
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def t1(): @asyncio.coroutine
return (yield from t2()) def t1():
return (yield from t2())
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def t2(): @asyncio.coroutine
f = self.new_future(self.loop) def t2():
self.new_task(self.loop, t3(f)) f = self.new_future(self.loop)
return (yield from f) self.new_task(self.loop, t3(f))
return (yield from f)
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def t3(f): @asyncio.coroutine
f.set_result((1, 2, 3)) def t3(f):
f.set_result((1, 2, 3))
task = self.new_task(self.loop, t1()) task = self.new_task(self.loop, t1())
val = self.loop.run_until_complete(task) val = self.loop.run_until_complete(task)
@ -2009,13 +2004,14 @@ class BaseTaskTests:
def test_log_destroyed_pending_task(self): def test_log_destroyed_pending_task(self):
Task = self.__class__.Task Task = self.__class__.Task
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def kill_me(loop): @asyncio.coroutine
future = self.new_future(loop) def kill_me(loop):
yield from future future = self.new_future(loop)
# at this point, the only reference to kill_me() task is yield from future
# the Task._wakeup() method in future._callbacks # at this point, the only reference to kill_me() task is
raise Exception("code never reached") # the Task._wakeup() method in future._callbacks
raise Exception("code never reached")
mock_handler = mock.Mock() mock_handler = mock.Mock()
self.loop.set_debug(True) self.loop.set_debug(True)
@ -2064,14 +2060,12 @@ class BaseTaskTests:
loop = asyncio.new_event_loop() loop = asyncio.new_event_loop()
self.set_event_loop(loop) self.set_event_loop(loop)
@asyncio.coroutine async def coro():
def coro():
raise TypeError raise TypeError
@asyncio.coroutine async def runner():
def runner():
task = self.new_task(loop, coro()) task = self.new_task(loop, coro())
yield from asyncio.sleep(0.05) await asyncio.sleep(0.05)
task.cancel() task.cancel()
task = None task = None
@ -2081,9 +2075,10 @@ class BaseTaskTests:
@mock.patch('asyncio.coroutines.logger') @mock.patch('asyncio.coroutines.logger')
def test_coroutine_never_yielded(self, m_log): def test_coroutine_never_yielded(self, m_log):
with set_coroutine_debug(True): with set_coroutine_debug(True):
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def coro_noop(): @asyncio.coroutine
pass def coro_noop():
pass
tb_filename = __file__ tb_filename = __file__
tb_lineno = sys._getframe().f_lineno + 2 tb_lineno = sys._getframe().f_lineno + 2
@ -2112,13 +2107,15 @@ class BaseTaskTests:
from @asyncio.coroutine()-wrapped function should have same effect as from @asyncio.coroutine()-wrapped function should have same effect as
returning generator object or Future.""" returning generator object or Future."""
def check(): def check():
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def outer_coro():
@asyncio.coroutine @asyncio.coroutine
def inner_coro(): def outer_coro():
return 1 with self.assertWarns(DeprecationWarning):
@asyncio.coroutine
def inner_coro():
return 1
return inner_coro() return inner_coro()
result = self.loop.run_until_complete(outer_coro()) result = self.loop.run_until_complete(outer_coro())
self.assertEqual(result, 1) self.assertEqual(result, 1)
@ -2147,11 +2144,10 @@ class BaseTaskTests:
loop = asyncio.new_event_loop() loop = asyncio.new_event_loop()
self.addCleanup(loop.close) self.addCleanup(loop.close)
@asyncio.coroutine async def blocking_coroutine():
def blocking_coroutine():
fut = self.new_future(loop) fut = self.new_future(loop)
# Block: fut result is never set # Block: fut result is never set
yield from fut await fut
task = loop.create_task(blocking_coroutine()) task = loop.create_task(blocking_coroutine())
@ -2230,14 +2226,12 @@ class BaseTaskTests:
def test_exception_traceback(self): def test_exception_traceback(self):
# See http://bugs.python.org/issue28843 # See http://bugs.python.org/issue28843
@asyncio.coroutine async def foo():
def foo():
1 / 0 1 / 0
@asyncio.coroutine async def main():
def main():
task = self.new_task(self.loop, foo()) task = self.new_task(self.loop, foo())
yield # skip one loop iteration await asyncio.sleep(0) # skip one loop iteration
self.assertIsNotNone(task.exception().__traceback__) self.assertIsNotNone(task.exception().__traceback__)
self.loop.run_until_complete(main()) self.loop.run_until_complete(main())
@ -2248,9 +2242,10 @@ class BaseTaskTests:
raise ValueError raise ValueError
self.loop.call_soon = call_soon self.loop.call_soon = call_soon
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def coro(): @asyncio.coroutine
pass def coro():
pass
self.assertFalse(m_log.error.called) self.assertFalse(m_log.error.called)
@ -2280,9 +2275,10 @@ class BaseTaskTests:
def test_create_task_with_oldstyle_coroutine(self): def test_create_task_with_oldstyle_coroutine(self):
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def coro(): @asyncio.coroutine
pass def coro():
pass
task = self.new_task(self.loop, coro()) task = self.new_task(self.loop, coro())
self.assertIsInstance(task, self.Task) self.assertIsInstance(task, self.Task)
@ -2553,8 +2549,7 @@ class CTask_CFuture_Tests(BaseTaskTests, SetMethodsTest,
@support.refcount_test @support.refcount_test
def test_refleaks_in_task___init__(self): def test_refleaks_in_task___init__(self):
gettotalrefcount = support.get_attribute(sys, 'gettotalrefcount') gettotalrefcount = support.get_attribute(sys, 'gettotalrefcount')
@asyncio.coroutine async def coro():
def coro():
pass pass
task = self.new_task(self.loop, coro()) task = self.new_task(self.loop, coro())
self.loop.run_until_complete(task) self.loop.run_until_complete(task)
@ -2565,8 +2560,7 @@ class CTask_CFuture_Tests(BaseTaskTests, SetMethodsTest,
self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10) self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10)
def test_del__log_destroy_pending_segfault(self): def test_del__log_destroy_pending_segfault(self):
@asyncio.coroutine async def coro():
def coro():
pass pass
task = self.new_task(self.loop, coro()) task = self.new_task(self.loop, coro())
self.loop.run_until_complete(task) self.loop.run_until_complete(task)
@ -3054,15 +3048,13 @@ class CoroutineGatherTests(GatherTestsBase, test_utils.TestCase):
def wrap_futures(self, *futures): def wrap_futures(self, *futures):
coros = [] coros = []
for fut in futures: for fut in futures:
@asyncio.coroutine async def coro(fut=fut):
def coro(fut=fut): return await fut
return (yield from fut)
coros.append(coro()) coros.append(coro())
return coros return coros
def test_constructor_loop_selection(self): def test_constructor_loop_selection(self):
@asyncio.coroutine async def coro():
def coro():
return 'abc' return 'abc'
gen1 = coro() gen1 = coro()
gen2 = coro() gen2 = coro()
@ -3078,9 +3070,10 @@ class CoroutineGatherTests(GatherTestsBase, test_utils.TestCase):
self.other_loop.run_until_complete(fut2) self.other_loop.run_until_complete(fut2)
def test_duplicate_coroutines(self): def test_duplicate_coroutines(self):
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def coro(s): @asyncio.coroutine
return s def coro(s):
return s
c = coro('abc') c = coro('abc')
fut = asyncio.gather(c, c, coro('def'), c, loop=self.one_loop) fut = asyncio.gather(c, c, coro('def'), c, loop=self.one_loop)
self._run_loop(self.one_loop) self._run_loop(self.one_loop)
@ -3091,21 +3084,19 @@ class CoroutineGatherTests(GatherTestsBase, test_utils.TestCase):
proof = 0 proof = 0
waiter = asyncio.Future(loop=self.one_loop) waiter = asyncio.Future(loop=self.one_loop)
@asyncio.coroutine async def inner():
def inner():
nonlocal proof nonlocal proof
yield from waiter await waiter
proof += 1 proof += 1
child1 = asyncio.ensure_future(inner(), loop=self.one_loop) child1 = asyncio.ensure_future(inner(), loop=self.one_loop)
child2 = asyncio.ensure_future(inner(), loop=self.one_loop) child2 = asyncio.ensure_future(inner(), loop=self.one_loop)
gatherer = None gatherer = None
@asyncio.coroutine async def outer():
def outer():
nonlocal proof, gatherer nonlocal proof, gatherer
gatherer = asyncio.gather(child1, child2, loop=self.one_loop) gatherer = asyncio.gather(child1, child2, loop=self.one_loop)
yield from gatherer await gatherer
proof += 100 proof += 100
f = asyncio.ensure_future(outer(), loop=self.one_loop) f = asyncio.ensure_future(outer(), loop=self.one_loop)
@ -3123,17 +3114,15 @@ class CoroutineGatherTests(GatherTestsBase, test_utils.TestCase):
def test_exception_marking(self): def test_exception_marking(self):
# Test for the first line marked "Mark exception retrieved." # Test for the first line marked "Mark exception retrieved."
@asyncio.coroutine async def inner(f):
def inner(f): await f
yield from f
raise RuntimeError('should not be ignored') raise RuntimeError('should not be ignored')
a = asyncio.Future(loop=self.one_loop) a = asyncio.Future(loop=self.one_loop)
b = asyncio.Future(loop=self.one_loop) b = asyncio.Future(loop=self.one_loop)
@asyncio.coroutine async def outer():
def outer(): await asyncio.gather(inner(a), inner(b), loop=self.one_loop)
yield from asyncio.gather(inner(a), inner(b), loop=self.one_loop)
f = asyncio.ensure_future(outer(), loop=self.one_loop) f = asyncio.ensure_future(outer(), loop=self.one_loop)
test_utils.run_briefly(self.one_loop) test_utils.run_briefly(self.one_loop)
@ -3152,15 +3141,14 @@ class RunCoroutineThreadsafeTests(test_utils.TestCase):
self.loop = asyncio.new_event_loop() self.loop = asyncio.new_event_loop()
self.set_event_loop(self.loop) # Will cleanup properly self.set_event_loop(self.loop) # Will cleanup properly
@asyncio.coroutine async def add(self, a, b, fail=False, cancel=False):
def add(self, a, b, fail=False, cancel=False):
"""Wait 0.05 second and return a + b.""" """Wait 0.05 second and return a + b."""
yield from asyncio.sleep(0.05) await asyncio.sleep(0.05)
if fail: if fail:
raise RuntimeError("Fail!") raise RuntimeError("Fail!")
if cancel: if cancel:
asyncio.current_task(self.loop).cancel() asyncio.current_task(self.loop).cancel()
yield await asyncio.sleep(0)
return a + b return a + b
def target(self, fail=False, cancel=False, timeout=None, def target(self, fail=False, cancel=False, timeout=None,
@ -3261,11 +3249,10 @@ class SleepTests(test_utils.TestCase):
nonlocal result nonlocal result
result += num result += num
@asyncio.coroutine async def coro():
def coro():
self.loop.call_soon(inc_result, 1) self.loop.call_soon(inc_result, 1)
self.assertEqual(result, 0) self.assertEqual(result, 0)
num = yield from asyncio.sleep(0, result=10) num = await asyncio.sleep(0, result=10)
self.assertEqual(result, 1) # inc'ed by call_soon self.assertEqual(result, 1) # inc'ed by call_soon
inc_result(num) # num should be 11 inc_result(num) # num should be 11
@ -3318,24 +3305,27 @@ class CompatibilityTests(test_utils.TestCase):
def test_yield_from_awaitable(self): def test_yield_from_awaitable(self):
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def coro(): @asyncio.coroutine
yield from asyncio.sleep(0) def coro():
return 'ok' yield from asyncio.sleep(0)
return 'ok'
result = self.loop.run_until_complete(coro()) result = self.loop.run_until_complete(coro())
self.assertEqual('ok', result) self.assertEqual('ok', result)
def test_await_old_style_coro(self): def test_await_old_style_coro(self):
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def coro1(): @asyncio.coroutine
return 'ok1' def coro1():
return 'ok1'
@asyncio.coroutine with self.assertWarns(DeprecationWarning):
def coro2(): @asyncio.coroutine
yield from asyncio.sleep(0) def coro2():
return 'ok2' yield from asyncio.sleep(0)
return 'ok2'
async def inner(): async def inner():
return await asyncio.gather(coro1(), coro2(), loop=self.loop) return await asyncio.gather(coro1(), coro2(), loop=self.loop)

View File

@ -1708,9 +1708,8 @@ class AsyncIteratorWrapper(typing.AsyncIterator[T_a]):
def __aiter__(self) -> typing.AsyncIterator[T_a]: def __aiter__(self) -> typing.AsyncIterator[T_a]:
return self return self
@asyncio.coroutine async def __anext__(self) -> T_a:
def __anext__(self) -> T_a: data = await self.value
data = yield from self.value
if data: if data:
return data return data
else: else:

View File

@ -0,0 +1 @@
Deprecate ``@coroutine`` for sake of ``async def``.