-
-
Notifications
You must be signed in to change notification settings - Fork 30.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Not all generators containing await
are compiled to async generators
#114104
Comments
cc @gvanrossum I think that it is easier to make the documentation more explicit. The iterable expression in the leftmost We can, of cause, change the implementation, but what is the use case for this? If you want to make an asynchronous generator and await gen = (x for _ in [1] for x in await foo()) But it is more clear to write an inner function: async def gen():
for x in await foo():
yield x In this way you can even make an asynchronous generator that does not contain any async def gen():
for x in sync_foo():
yield x |
The behavior is as intended. If that's not clear from the docs, those doc should be updated. |
Fixes #10534 This PR fixes a bug in typechecking asynchronous generators. Mypy currently typechecks a generator/comprehension as `AsyncGenerator` if the leftmost expression contains `await`, or if it contains an `async for`. However, there are other situations where we should get async generator: If there is an `await` expression in any of the conditions or in any sequence except for the leftmost one, the generator/comprehension should also be typechecked as `AsyncGenerator`. I've implemented this change in Mypy and added a test case to assert this behavior. If I enter the test cases into a regular repl, I can confirm that the runtime representation is generator/async_generator as the test case expects. According to the [language reference](https://docs.python.org/3/reference/expressions.html#grammar-token-python-grammar-comp_for): > If a comprehension contains either async for clauses or await expressions or other asynchronous comprehensions it is called an asynchronous comprehension. Confusingly, the documentation itself is actually not quite correct either, as pointed out in python/cpython#114104 Alongside this change, I've made a PR to update the docs to be more precise: python/cpython#121175 has more details.
…time behavior (pythonGH-121175) (cherry picked from commit 91313af) Co-authored-by: Danny Yang <yangdanny97@users.noreply.github.com>
…time behavior (pythonGH-121175) (cherry picked from commit 91313af) Co-authored-by: Danny Yang <yangdanny97@users.noreply.github.com>
Documentation
A generator of the form
f(x) for x in await a
first awaitsa
and then creates a regular syncgenerator
, as can be seen in the following minimal reproducer:However the python language reference 6.2.8. Generator expressions states:
This seems to suggest that the generator
f(x) for x in await a
does contain an await expression, so it should become anasync_generator
? However there is also:This seems to hint at an implementation detail that the leftmost
for
clause has special treatment and is always evaluated before the generator is constructed, but the interactions withawait
are unclear from this, especially whether this disqualifies the generator from becoming async.I don't know whether this is an undocumented feature or a bug.
Linked PRs
The text was updated successfully, but these errors were encountered: