Skip to content

Instantly share code, notes, and snippets.

@bukzor
Created July 10, 2025 16:52
Show Gist options
  • Save bukzor/f770a3e8c75de5edff64c47e55afb657 to your computer and use it in GitHub Desktop.
Save bukzor/f770a3e8c75de5edff64c47e55afb657 to your computer and use it in GitHub Desktop.
a half-baked `gather` for `concurrent.futures`
import threading
from concurrent.futures import Future
from typing import TypeVar
T = TypeVar("T")
def gather(*futures: Future[T], return_exceptions=False) -> Future[list[T]]:
if return_exceptions:
raise NotImplementedError("concurrent.futures.gather: can't yet return_exceptions")
all_done: Future[list[T]] = Future()
counter = threading.Semaphore(len(futures))
def check_all_done(future):
del future # unused
if not counter.acquire(blocking=False):
try:
all_done.set_result([future.result() for future in futures])
except Exception as e:
all_done.set_exception(e)
check_all_done(None)
for future in futures:
future.add_done_callback(check_all_done)
return all_done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment