Commit 68b34a72 authored by Andrew Svetlov's avatar Andrew Svetlov Committed by Miss Islington (bot)

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
parent dbacfc22
...@@ -916,12 +916,13 @@ enforced. ...@@ -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>`.
......
...@@ -7,6 +7,7 @@ import os ...@@ -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): ...@@ -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".
......
...@@ -3,12 +3,13 @@ ...@@ -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: ...@@ -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: ...@@ -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)
......
...@@ -23,7 +23,7 @@ from . import coroutines ...@@ -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): ...@@ -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): ...@@ -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().
......
...@@ -575,9 +575,8 @@ class BaseEventLoopTests(test_utils.TestCase): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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()
......
...@@ -253,12 +253,10 @@ class EventLoopTestsMixin: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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): ...@@ -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>'
......
...@@ -44,10 +44,11 @@ class LockTests(test_utils.TestCase): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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())
......
...@@ -130,9 +130,10 @@ class CoroutineTests(BaseTest): ...@@ -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')
......
...@@ -588,8 +588,7 @@ class StreamTests(test_utils.TestCase): ...@@ -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)
......
This diff is collapsed.
...@@ -1708,9 +1708,8 @@ class AsyncIteratorWrapper(typing.AsyncIterator[T_a]): ...@@ -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:
......
Deprecate ``@coroutine`` for sake of ``async def``.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment