asyncio eager task inherits the creators exception state
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- Python
- Estrellas
- 77.2k
- Forks
- 35.9k
- Métricas de merge de PR
- Métricas de PR pendientes
Descripción
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
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Línea de trabajo
Comienza reproduciendo el comportamiento de las tareas eager en el ejemplo de asyncio del issue e inspecciona el punto de entrada task_eager_start. Compara el manejo de excepciones eager y no eager y, después, verifica que se produzca la salida esperada indicada sin cambiar la implementación independiente de Python de las tareas.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- c, python
- Área
- backend
- Tipo de issue
- Error
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Estado de actividad
- Estancado
- Claridad
- Bien especificado
- Aptitud para principiantes
- 30/100