[Python-ideas] async/await in Python

Yury Selivanov yselivanov.ml at gmail.com
Sat Apr 18 00:56:37 CEST 2015


Chris,
On 2015-04-17 6:46 PM, Chris Angelico wrote:
> On Sat, Apr 18, 2015 at 8:18 AM, Yury Selivanov <yselivanov.ml at gmail.com> wrote:
>> On 2015-04-17 6:00 PM, Chris Angelico wrote:
>>> On Sat, Apr 18, 2015 at 4:58 AM, Yury Selivanov <yselivanov.ml at gmail.com>
>>> wrote:
>>>
[...]
>>> Can't a coroutine simply use 'return'? I'm not hugely familiar with
>>> them, but I'm not understanding here why you need a completely
>>> separate exception - and, more importantly, why you wouldn't have the
>>> same consideration of "StopAsyncIteration leakage". It ought to be
>>> possible for the coroutine to return, StopIteration be synthesized,
>>> and the __anext__ function to bubble that out - exactly the way it
>>> does for generators today.
>>
>> Unfortunately, there is no way we can enable StopIteration to do
>> the same thing that StopAsyncIteration does.
>>
>> 'return' in coroutines is implemented with 'StopIteration' exception
>> internally, so there is no way (without ugly hacks) to distinguish
>> before plain returns and desire to stop the iteration.
> All you need to do is have the same StopIteration -> RuntimeError
> handling that PEP 479 proposes, and then you can confidently accept a
> StopIteration coming out of __anext__ as a signal that the coroutine
> returned. It might require a small hack during the transitional time
> (eg "all functions defined with 'async def' behave as if defined in
> the presence of a 'from __future__ import generator_stop' directive"),
> but once PEP 479 handling becomes standard, generators and coroutines
> will all always follow this distinction. Generators either yield or
> return, coroutines either await or return, __[a]next__ methods either
> return or raise StopIteration, and any other issues become exceptions
> that bubble up.
>
> Since you're already utilizing a lot of generator-like behaviour, it
> shouldn't be a problem to handle exceptions the same way. The logic
> around a generator's __next__ method is broadly thus:
>
> * Resume the function's execution
> * If it returned: Synthesize a StopIteration.
> * Else if it raised StopIteration: Raise RuntimeError.
> * Else if it raised anything else: Let it bubble up.
> * Else it yielded something, so return it.
>
> There's no conflict here, because they're checked in strict order. It
> ought to be possible to do the same thing. The only reason for messy
> hacks is to support Python 2.x, where "return X" (for any X other than
> None) doesn't work; given that you're adding new syntax here, the
> concern shouldn't apply.

You forget that '__anext__' can be implemented as 'async def'
function, as well as a regular 'def' returning an *awaitable*
object, such as asyncio.Future or generator wrapped in
'types.async_def'.

All in all, I think that it's probably possible to implement
what you suggest.  But I also believe that having a new
built-in exception for the new protocol is a 100% better
solution, simpler to implement and explain in documentation.


>
>> Let's see what python-ideas thinks about it.  I'm fine if everybody
>> wants __future__ imports.  I will only have to rollback my changes
>> in tokenizer.c and change few tokens in Grammar to make the
>> reference implementation work.
> In case it wasn't clear from my previous post, I'm +1 on using a
> __future__ import. Victor's idea of an optional directive seems
> interesting, but I'm not sure how useful it'd be in reality; does
> complicating the rules offer more benefit than simply having a keyword
> governed by __future__?
I'm OK with __future__ import.  And I'll be extremely happy
if that's the only thing we'll be all discussing here ;-)

Let's see how the discussion goes, and if everybody on the
list wants __future__ and Guido approves, I'll update
the PEP and ref implementation!

>
>>>> Comprehensions
>>>> --------------
>>>>
>>>> For the sake of restricting the broadness of this PEP there is no new
>>>> syntax
>>>> for asynchronous comprehensions.  This should be considered in a separate
>>>> PEP,
>>>> if there is a strong demand for this feature.
>>> Likewise asynchronous lambda functions (or maybe I just missed it).
>> Right. Right now I'm just not sure they would be useful at all,
>> whereas I can imagine some usecases for comprehensions ;)
> Sure. I'm making no statement as to whether or not async lambda is
> worth implementing, but just that it's another subproposal that isn't
> being dealt with in this PEP.
I think you're right, I need to add 'async lambda'
to the 'Design Considerations' section.

Thanks!

Yury


More information about the Python-ideas mailing list