asyncio eager task inherits the creators exception state
オープン
まだ誰も着手していません。
stdlib
topic-asyncio
type-bug
- 主要言語
- Python
- スター
- 77.2k
- フォーク
- 36k
- PR マージ指標
- PR 指標を取得中
説明
Bug report
Bug description:
Eager tasks created from an except block inherits the creator's exception state, a bare raise re-raises it, and any other exception gets it as __context__.
Repro:
import asyncio
async def bare():
raise
async def explicit():
raise ValueError("child's own")
async def main(coro):
try:
raise ConnectionError("primary failed")
except ConnectionError:
t = asyncio.create_task(coro)
try:
await t
except BaseException as e:
print(f" {type(e).__name__}: {e} | __context__: {e.__context__!r}")
for eager in (False, True):
print("eager_task_factory:", eager)
for coro_fn in (bare, explicit):
loop = asyncio.new_event_loop()
if eager:
loop.set_task_factory(asyncio.eager_task_factory)
try:
loop.run_until_complete(main(coro_fn()))
finally:
loop.close()
expected:
eager_task_factory: False
RuntimeError: No active exception to reraise | __context__: None
ValueError: child's own | __context__: None
eager_task_factory: True
RuntimeError: No active exception to reraise | __context__: None
ValueError: child's own | __context__: None
actually:
eager_task_factory: False
RuntimeError: No active exception to reraise | __context__: None
ValueError: child's own | __context__: None
eager_task_factory: True
ConnectionError: primary failed | __context__: None
ValueError: child's own | __context__: ConnectionError('primary failed')
proposed fix - run the eager first step under an empty exception state in task_eager_start
_PyErr_StackItem exc_state = { .exc_value = NULL, .previous_item = NULL };
_PyErr_StackItem *prev_exc_info = ts->base.exc_info;
ts->base.exc_info = &exc_state;
Py_BEGIN_CRITICAL_SECTION(task);
stepres = task_step_impl(state, task, NULL);
Py_END_CRITICAL_SECTION();
ts->base.exc_info = prev_exc_info;
This error also affects python implementation of task, but i think this needs a discussion in a separate issue
Have a fix ready
CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS
Linked PRs
- gh-155578
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
まず、issue の asyncio の例で eager-task の動作を再現し、task_eager_start エントリーポイントを調べます。eager と non-eager の例外処理を比較し、その後、別個の Python タスク実装を変更せずに、報告されている期待される出力が生成されることを確認します。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- c, python
- 領域
- backend
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 停滞
- 明瞭さ
- 明確に書かれている
- 初心者へのやさしさ
- 30/100