Cancel futures if concurrent.futures.Executor is used as a context manager and there is an exception?
@gpshead 已經在處理了。
開始於 2026年6月13日。
- 主要語言
- Python
- 星號
- 77.2k
- 分支
- 36k
- PR 合併指標
- PR 指標待擷取
描述
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.
貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
評估
這個 Issue 還沒有評估資料。