python / python/cpython

Implement `anext` and `aiter` in pure Python

オープン
#157,361 コメント 8 件 リアクション 2 件 担当者 1 名 GitHub で見る

@kumaraditya303 がすでに取り組んでいます。

2026年9月12日 から。

3.16 interpreter-core topic-asyncio type-feature
主要言語
Python
スター
77.2k
フォーク
35.9k
PR マージ指標
PR 指標を取得中

説明

Feature or enhancement

Feature or enhancement

I propose to implement anext() and aiter() in Python instead of C, compiled at interpreter startup and copied into builtins. This removes the private anext_awaitable, async_callable_iterator and async_callable_iterator_awaitable types.

anext(it, default) becomes a plain coroutine that awaits type(it).__anext__(it) and converts StopAsyncIteration into the default. The callable form of aiter() (gh-64862) becomes a small class with async def __anext__ that calls and awaits the callable and turns the sentinel or stop_exception into StopAsyncIteration. Semantics stay the same.

The motivation is #157032 and #157044: the C awaitables break the asyncio await graph. capture_call_graph walks cr_await/ag_await, and these types have neither, so the graph stops at the frame calling anext(it, default) or iterating aiter(callable, sentinel) and hides where the task is actually suspended. This would fix #157032, #157044 without any special casing.

Repro with a class-based async iterator:

import asyncio

async def fetch():
    await asyncio.sleep(10)

class AIter:
    def __aiter__(self): return self
    async def __anext__(self):
        await fetch()
        return 1

async def consumer():
    await anext(AIter(), None)

async def main():
    t = asyncio.create_task(consumer(), name="consumer")
    for _ in range(3):
        await asyncio.sleep(0)
    asyncio.print_call_graph(t)
    t.cancel()

asyncio.run(main())

Before:

* Task(name='consumer', id=0x10a42c7d0)
  + Call stack:
  |   File 'demo.py', line 13, in async consumer()

After:

* Task(name='consumer', id=0x108959b80)
  + Call stack:
  |   File 'Lib/asyncio/tasks.py', line 707, in async sleep()
  |   File 'demo.py', line 4, in async fetch()
  |   File 'demo.py', line 9, in async AIter.__anext__()
  |   File '<builtins>', line 26, in async _anext_with_default()
  |   File 'demo.py', line 13, in async consumer()
Linked PRs
  • gh-157362
  • gh-157687

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。