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
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4