asyncio eager task inherits the creators exception state
Personne n'a encore pris cette issue.
- Langage dominant
- Python
- Étoiles
- 77.2k
- Forks
- 35.9k
- Métriques de merge des PR
- Métriques de PR en attente
Description
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
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez par reproduire le comportement des tâches eager dans l’exemple asyncio de l’issue et examinez le point d’entrée task_eager_start. Comparez la gestion des exceptions eager et non eager, puis vérifiez que la sortie attendue indiquée est produite sans modifier l’implémentation Python distincte des tâches.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- c, python
- Domaine
- backend
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- À l'abandon
- Clarté
- Clairement spécifiée
- Accessibilité débutants
- 30/100