[Python-Dev] async/await in Python; v2

Yury Selivanov yselivanov.ml at gmail.com
Wed Apr 22 19:13:24 CEST 2015


Hi Rajiv,

On 2015-04-22 12:53 PM, Rajiv Kumar wrote:
> I'd like to suggest another way around some of the issues here, with
> apologies if this has already been discussed sometime in the past.
>
>  From the viewpoint of a Python programmer, there are two distinct reasons
> for wanting to suspend execution in a block of code:
>
> 1. To yield a value from an iterator, as Python generators do today.
>
> 2. To cede control to the event loop while waiting for an asynchronous task
> to make progress in a coroutine.
>
> As of today both of these reasons to suspend are supported by the same
> underlying mechanism, i.e. a "yield" at the end of the chain of "yield
> from"s. PEPs 492 and 3152 introduce "await" and "cocall", but at the bottom
> of it all there's effectively still a yield as I understand it.
>
> I think that the fact that these two concepts use the same mechanism is
> what leads to the issues with coroutine-generators that Greg and Yury have
> raised.
>
> With that in mind, would it be possible to introduce a second form of
> suspension to Python to specifically handle the case of ceding to the event
> loop? I don't know what the implementation complexity of this would be, or
> if it's even feasible. But roughly speaking, the syntax for this could use
> "await", and code would look just like it does in the PEP. The semantics of
> "await <Task>" would be analogous to "yield from <Task>" today, with the
> difference that the Task would go up the chain of "await"s to the outermost
> caller, which would typically be asyncio, with some modifications from its
> form today. Progress would be made via __anext__ instead of __next__.

I think that what you propose is a great idea. However, its
implementation will be far more invasive than what PEP 492
proposes.  I doubt that we'll be able to make it in 3.5 if
we choose this route.

BUT: With my latest proposal to disallow for..in loops and
iter()/list()-like builtins, the fact that coroutines are
based internally on generators is just an implementation
detail.

There is no way users can exploit the underlying generator
object.  Coroutine-objects only provide 'send()' and 'throw()'
methods, which they would also have with your implementation
idea.

This gives us freedom to consider your approach in 3.6 if
we decide to add coroutine-generators.  To make this work
we might want to patch inspect.py to make isgenerator() family
of functions to return False for coroutines/coroutine-objects.

Thanks a lot for the feedback!
Yury


More information about the Python-Dev mailing list