Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 620279b

Browse files
committed
asyncio: ensure_future() now understands awaitables
1 parent e2382c5 commit 620279b

2 files changed

Lines changed: 32 additions & 2 deletions

File tree

Lib/asyncio/tasks.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ def async(coro_or_future, *, loop=None):
512512

513513

514514
def ensure_future(coro_or_future, *, loop=None):
515-
"""Wrap a coroutine in a future.
515+
"""Wrap a coroutine or an awaitable in a future.
516516
517517
If the argument is a Future, it is returned directly.
518518
"""
@@ -527,8 +527,20 @@ def ensure_future(coro_or_future, *, loop=None):
527527
if task._source_traceback:
528528
del task._source_traceback[-1]
529529
return task
530+
elif compat.PY35 and inspect.isawaitable(coro_or_future):
531+
return ensure_future(_wrap_awaitable(coro_or_future), loop=loop)
530532
else:
531-
raise TypeError('A Future or coroutine is required')
533+
raise TypeError('A Future, a coroutine or an awaitable is required')
534+
535+
536+
@coroutine
537+
def _wrap_awaitable(awaitable):
538+
"""Helper for asyncio.ensure_future().
539+
540+
Wraps awaitable (an object with __await__) into a coroutine
541+
that will later be wrapped in a Task by ensure_future().
542+
"""
543+
return (yield from awaitable.__await__())
532544

533545

534546
class _GatheringFuture(futures.Future):

Lib/test/test_asyncio/test_tasks.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,24 @@ def notmuch():
153153
t = asyncio.ensure_future(t_orig, loop=self.loop)
154154
self.assertIs(t, t_orig)
155155

156+
@unittest.skipUnless(PY35, 'need python 3.5 or later')
157+
def test_ensure_future_awaitable(self):
158+
class Aw:
159+
def __init__(self, coro):
160+
self.coro = coro
161+
def __await__(self):
162+
return (yield from self.coro)
163+
164+
@asyncio.coroutine
165+
def coro():
166+
return 'ok'
167+
168+
loop = asyncio.new_event_loop()
169+
self.set_event_loop(loop)
170+
fut = asyncio.ensure_future(Aw(coro()), loop=loop)
171+
loop.run_until_complete(fut)
172+
assert fut.result() == 'ok'
173+
156174
def test_ensure_future_neither(self):
157175
with self.assertRaises(TypeError):
158176
asyncio.ensure_future('ok')

0 commit comments

Comments
 (0)