python / python/cpython

Cancel futures if concurrent.futures.Executor is used as a context manager and there is an exception?

Abierto
#130,975 2 comentarios 3 reacciones 1 asignado Ver en GitHub

@gpshead ya está trabajando en esto.

Desde el 13/6/2026.

stdlib type-feature
Lenguaje dominante
Python
Estrellas
77.2k
Forks
35.9k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

I bumped into a bit of a rough edge related to how concurrent.futures.Executor instances behave when they're used as context managers and there is an exception raised from the with statement body.

I had some code like this (reduced to the bare minimum):

with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
    futures = {
        executor.submit(check_status, item): item
        for item in to_check
    }
    for index, future in enumerate(concurrent.futures.as_completed(futures)):
        print(f"{index}/{len(futures)} {future.result()}")

Now, as it happens check_status liked to raise an exception from time to time and this would be fine if the application stopped because of that but it kept going but in a weird way. What I saw was check_status kept producing logs but the print calls in the snippet above stopped being executed.

This is because of how Executor implements __exit__ – it waits for all pending futures to complete before propagating the exception:

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.shutdown(wait=True)
        return False

No in my case I started with thousands of futures so it could take hours for the process to finally crash.

Since Python 3.9 the shutdown method has the cancel_futures parameter (implemented in https://github.com/python/cpython/pull/18057): https://docs.python.org/3.9/library/concurrent.futures.html#concurrent.futures.Executor.shutdown.

I'm proposing changing the behavior of the context manager __exit__ to cancel futures if there is an exception:

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.shutdown(wait=True, cancel_futures=exc_val is not None)
        return False

This would allow the in-flight futures to finish but any further processing wouldn't happen and the exception would be reported in a (more) timely fashion.

cc @brianquinlan @pitrou as I saw you participate in the cancel_futures PR, if there's someone else I should ping here for visibility please let me know.

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.