asyncio eager task inherits the creators exception state
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Python
- Sterne
- 77.2k
- Forks
- 35.9k
- PR-Merge-Kennzahlen
- PR-Kennzahlen ausstehend
Beschreibung
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
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne damit, das Verhalten von eager tasks im asyncio-Beispiel des Issues zu reproduzieren, und untersuche den Einstiegspunkt task_eager_start. Vergleiche die Ausnahmebehandlung bei eager und nicht-eager tasks und überprüfe anschließend, dass die gemeldete erwartete Ausgabe erzeugt wird, ohne die separate Python-Task-Implementierung zu ändern.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- c, python
- Bereich
- backend
- Issue-Typ
- Bug
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Aktivitätsstatus
- Veraltet
- Klarheit
- Klar beschrieben
- Anfängerfreundlichkeit
- 30/100