[Python-Dev] async/await behavior on multiple calls

Roy Williams rwilliams at lyft.com
Tue Dec 15 14:56:43 EST 2015


Howdy,

I'm experimenting with async/await in Python 3, and one very surprising
behavior has been what happens when calling `await` twice on an Awaitable.
In C#, Hack/HHVM, and the new async/await spec in Ecmascript 7.  In Python,
calling `await` multiple times results in all future results getting back
`None`.  Here's a small example program:


async def echo_hi():
    result = ''
    echo_proc = await asyncio.create_subprocess_exec(
            'echo', 'hello', 'world',
            stdout=asyncio.subprocess.PIPE,
            stderr=asyncio.subprocess.DEVNULL)
    result = await echo_proc.stdout.read()
    await echo_proc.wait()
    return result

async def await_twice(awaitable):
    print('first time is {}'.format(await awaitable))
    print('second time is {}'.format(await awaitable))

loop = asyncio.get_event_loop()
loop.run_until_complete(await_twice(echo_hi()))

This makes writing composable APIs using async/await in Python very
difficult since anything that takes an `awaitable` has to know that it
wasn't already awaited.  Also, since the behavior is radically different
than in the other programming languages implementing async/await it makes
adopting Python's flavor of async/await difficult for folks coming from a
language where it's already implemented.

In C#/Hack/JS calls to `await` return a Task/AwaitableHandle/Promise that
can be awaited multiple times and either returns the result or throws any
thrown exceptions.  It doesn't appear that the Awaitable class in Python
has a `result` or `exception` field but `asyncio.Future` does.

Would it make sense to shift from having `await` functions return a `
*Future-like`* return object to returning a Future?

Thanks,
Roy
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20151215/61b80bfa/attachment.html>


More information about the Python-Dev mailing list