python / python/cpython

Clarify that generator containing an async list comprehension becomes an async generator

Open
#138,097 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

docs type-bug
Dominant language
Python
Stars
77.2k
Forks
35.9k
PR merge metrics
PR metrics pending

Description

Bug report

Bug description:
import asyncio


async def foo():
    print(x for x in [1])  # <generator object foo.<locals>.<genexpr> at 0x...>
    print([a async for a in b] for x in [1])  # <async_generator object foo.<locals>.<genexpr> at 0x...>


asyncio.run(foo())

This happens only if the genexp contains an async listcomp inside of it:

[snip]

This makes sense because the inner listcomp is async and therefore must be evaluated within an async context. It's not clearly documented, though: https://docs.python.org/3.14/reference/expressions.html#generator-expressions says "If a generator expression contains either async for clauses or await expressions it is called an asynchronous generator expression. An asynchronous generator expression returns a new asynchronous generator object, which is an asynchronous iterator (see Asynchronous Iterators)." However, I wouldn't necessarily expect that to include async for expressions in a nested scope. Also, when a genexp includes an async genexp, the outer genexp doesn't become async.

So I'd recommend that you open a CPython bug report to have this clarified in the documentation.

Originally posted by @JelleZijlstra in https://github.com/microsoft/pyright/discussions/10827#discussioncomment-14179632

CPython versions tested on:

3.13

Operating systems tested on:

No response

Linked PRs
  • gh-138105

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the Generator expressions section of the Python expressions reference at the linked documentation URL, and compare its definition of asynchronous generator expressions with the reported nested async list-comprehension example. Clarify when the outer generator expression becomes asynchronous, including the distinction from an outer expression containing an async generator expression. Check the related CPython issue gh-138105 before proceeding.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
documentation
Issue type
Documentation
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.