diff -r 6703ac68bf49 Lib/asyncio/tasks.py --- a/Lib/asyncio/tasks.py Fri Jul 31 23:36:00 2015 +0200 +++ b/Lib/asyncio/tasks.py Sat Aug 01 02:09:33 2015 +0300 @@ -249,15 +249,21 @@ result._blocking = False result.add_done_callback(self._wakeup) self._fut_waiter = result - if self._must_cancel: - if self._fut_waiter.cancel(): - self._must_cancel = False + if self._must_cancel and self._fut_waiter.cancel(): + self._must_cancel = False else: self._loop.call_soon( self._step, None, RuntimeError( 'yield was used instead of yield from ' 'in task {!r} with {!r}'.format(self, result))) + elif isinstance(result, concurrent.futures.Future): + if self._must_cancel and self._fut_waiter.cancel(): + self._must_cancel = False + result.add_done_callback( + functools.partial( + self._loop.call_soon_threadsafe, self._wakeup)) + self._fut_waiter = result elif result is None: # Bare yield relinquishes control for one event loop iteration. self._loop.call_soon(self._step) diff -r 6703ac68bf49 Lib/concurrent/futures/_base.py --- a/Lib/concurrent/futures/_base.py Fri Jul 31 23:36:00 2015 +0200 +++ b/Lib/concurrent/futures/_base.py Sat Aug 01 02:09:33 2015 +0300 @@ -315,6 +315,12 @@ hex(id(self)), _STATE_TO_DESCRIPTION_MAP[self._state]) + def __await__(self): + if not self.done(): + yield self + assert self.done(), "yield from wasn't used with future" + return self.result() # May raise too. + def cancel(self): """Cancel the future if possible.