HPI/my/core/utils/concurrent.py
Dima Gerasimov 18529257e7 core.common: move DummyExecutor to core.common.utils.concurrent
without backwards compat, unlikely it's been used by anyone
2024-08-16 10:22:29 +01:00

51 lines
1.5 KiB
Python

from concurrent.futures import Future, Executor
import sys
from typing import Any, Callable, Optional, TypeVar, TYPE_CHECKING
from ..compat import ParamSpec
_P = ParamSpec('_P')
_T = TypeVar('_T')
# https://stackoverflow.com/a/10436851/706389
class DummyExecutor(Executor):
"""
This is useful if you're already using Executor for parallelising,
but also want to provide an option to run the code serially (e.g. for debugging)
"""
def __init__(self, max_workers: Optional[int] = 1) -> None:
self._shutdown = False
self._max_workers = max_workers
if TYPE_CHECKING:
if sys.version_info[:2] <= (3, 8):
# 3.8 doesn't support ParamSpec as Callable arg :(
# and any attempt to type results in incompatible supertype.. so whatever
def submit(self, fn, *args, **kwargs): ...
else:
def submit(self, fn: Callable[_P, _T], /, *args: _P.args, **kwargs: _P.kwargs) -> Future[_T]: ...
else:
def submit(self, fn, *args, **kwargs):
if self._shutdown:
raise RuntimeError('cannot schedule new futures after shutdown')
f: Future[Any] = Future()
try:
result = fn(*args, **kwargs)
except KeyboardInterrupt:
raise
except BaseException as e:
f.set_exception(e)
else:
f.set_result(result)
return f
def shutdown(self, wait: bool = True, **kwargs) -> None:
self._shutdown = True