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

Andrew Svetlov andrew.svetlov at gmail.com
Wed Apr 22 20:32:40 CEST 2015


For now I can use mix asyncio.coroutines and `async def` functions, I
mean I can write `await f()` inside async def to call
asyncio.coroutine `f` and vise versa: I can use `yield from g()`
inside asyncio.coroutine to call `async def g(): ...`.

If we forbid to call `async def` from regualr code how asyncio should
work? I'd like to push `async def` everywhere in asyncio API where
asyncio.coroutine required.

On Wed, Apr 22, 2015 at 8:13 PM, Yury Selivanov <yselivanov.ml at gmail.com> wrote:
> 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
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> https://mail.python.org/mailman/options/python-dev/andrew.svetlov%40gmail.com



-- 
Thanks,
Andrew Svetlov


More information about the Python-Dev mailing list