[Python-Dev] PEP 492 vs. PEP 3152, new round (original) (raw)

Yury Selivanov yselivanov.ml at gmail.com
Fri Apr 24 19:50:41 CEST 2015


Guido,

On 2015-04-24 1:03 PM, Guido van Rossum wrote:

3. syntactic priority of await Yury, could you tweak the syntax for await so that we can write the most common usages without parentheses? In particular I'd like to be able to write _ _return await foo()_ _with await foo() as bar: ..._ _foo(await bar(), await bletch())_ _ (I don't care about await foo() + await bar() but it would be okay.) ``` I think this is reasonable with some tweaks of the grammar (similar to what Greg did for cocall, but without requiring call syntax at the end). I don't remember the reason why yield requires parentheses in expressions, hopefully it's not something fundamental. This has always annoyed me, so let's try to fix that for await. I'll experiment.

Ditto for _aiter_ and _anext_. I guess this means that the async equivalent to obtaining an iterator through it = iter(xs) followed by for x over it will have to look like ait = await aiter(xs) followed by for x over ait, where an iterator is required to have an _aiter_ method that's an async function and returns self immediately. But what if you left out the await from the first call? I.e. can this work? ``` ait = aiter(xs) async for x in ait: print(x)

With the current semantics that PEP 492 proposes, "await" for "aiter()" is mandatory.

You have to write

 ait = await aiter(xs)
 async for x in ait:
     print(c)

We can add some logic that will check that the iterator passed to 'async for' is not an unresolved awaitable and resolve it (instead of immediately checking if it has anext method), but that will complicate the implementation. It will also introduce more than one way of doing things. I think that users will recognize "async builtins" (when we add them) by the first letter "a" and use them in "await" expressions consistently.

```_ _The question here is whether the object returned by aiter(xs) has an_ __aiter_ method. Since it was intended to be the target of await, it_ _has an _await_ method. But that itself is mostly an alias for_ __iter_, not _aiter_. I guess it can be made to work, the object just has to implement a bunch of different protocols. Correct. And yes, we address this all by having iteration protocols clearly separated.

6. StopAsyncException I'm not sure about this. The motivation given in the PEP seems to focus on the need for _anext_ to be async. But is this really the right pattern? What if we required ait._anext_() to return a future, which can either raise good old StopIteration or return the next value from the iteration when awaited? I'm wondering if there are a few alternatives to be explored around the async iterator protocol still. anext should return an awaitable (following the terminology of the PEP), which can be a coroutine-object. I'm not sure that with semantics of PEP 479 it can actually raise StopIteration (without some hacks in genobject).

I'm also trying to think forward about how we can add generator-coroutines (the ones that combine 'await' and some form of 'yield') to make writing asynchronous iterators easier. I think that reusing StopIteration on that level will be a very hard thing to understand and implement.

I'll experiment with reference implementation and update the PEP.

Thank you, Yury



More information about the Python-Dev mailing list