[Python-Dev] Importance of "async" keyword

Nick Coghlan ncoghlan at gmail.com
Fri Jul 3 11:40:04 CEST 2015


On 3 July 2015 at 06:55, Sven R. Kunze <srkunze at mail.de> wrote:
> My understanding of coloring is "needs special treatment".
>
> Being special or not (containing an 'await' or not), as long as I don't need
> to care, I can call them either way (with 'await' or not) and each case
> works sensibly that's fine with me.

I'm afraid you're going to be disappointed in that regard, as wishing
that event driven programs behaved more like synchronous programs is
like wishing that complex numbers behaved like real numbers. There's
an extra level of complexity that is being deliberately introduced in
order to improve Python's ability to express certain kinds of
algorithms, and it isn't effective to just try to wish that complexity
away.

The payoff is that code that otherwise needs to be written as a long
series of disconnected callback chains (as has long been possible with
Twisted) can instead be written to look more like comparable
synchronous code (and this approach should bring with it much improved
introspection support, at least in 3.5+ now that gi_yieldfrom and
cr_await are being exposed at the Python level).

> Sensible would be something similar to:
> await function: suspension point and runs the function until completion
> call awaitable: runs the awaitable until completion

These both fail, and deliberately so: we don't know what they're
supposed to mean, and we refuse the temptation to guess. They're also
quite likely to indicate a bug (e.g. forgetting to call a native
coroutine function to get the coroutine out of it, forgetting to wait
for an awaitable) rather than something folks have done deliberately.

It's possible shorthand adapters may emerge over time, like:

    # Call awaitable from synchronous code
    def wait_for_result(awaitable):
        """Usage: result = asyncio.wait_for_result(awaitable)"""
       return asyncio.get_event_loop().run_until_complete(awaitable.__await__())

    # Call blocking operation from asynchronous code
   def blocking_call(f, *args, **kwds):
        """Usage: result = await asyncio.blocking_call(f, *args, **kwds))"""
        cb = functools.partial(f, *args, **kwds)
        return asyncio.get_event_loop().run_in_executor(cb)

However, those can be written already as utility functions, so we can
wait and see how strong the demand is for them as adapters. (They may
also be potentially useful to have as recipes in the documentation)

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia


More information about the Python-Dev mailing list