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 _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com