diff --git a/billiard-stubs/__init__.pyi b/billiard-stubs/__init__.pyi index e7f3077..a1ba95c 100644 --- a/billiard-stubs/__init__.pyi +++ b/billiard-stubs/__init__.pyi @@ -1,2 +1,172 @@ +from collections.abc import Callable, Iterable +from ctypes import Array as _CTypesArray +from ctypes import _CData +from logging import Logger +from multiprocessing import ( + AuthenticationError as AuthenticationError, +) +from multiprocessing import ( + BufferTooShort as BufferTooShort, +) +from multiprocessing import ( + ProcessError as ProcessError, +) +from multiprocessing import ( + TimeoutError as TimeoutError, +) +from multiprocessing.context import BaseContext +from multiprocessing.managers import SyncManager +from multiprocessing.queues import ( + JoinableQueue as _JoinableQueue, +) +from multiprocessing.queues import ( + Queue as _Queue, +) +from multiprocessing.queues import ( + SimpleQueue as _SimpleQueue, +) +from multiprocessing.sharedctypes import SynchronizedBase +from multiprocessing.synchronize import ( + Barrier as _Barrier, +) +from multiprocessing.synchronize import ( + BoundedSemaphore as _BoundedSemaphore, +) +from multiprocessing.synchronize import ( + Condition as _Condition, +) +from multiprocessing.synchronize import ( + Event as _Event, +) +from multiprocessing.synchronize import ( + Lock as _Lock, +) +from multiprocessing.synchronize import ( + RLock as _RLock, +) +from multiprocessing.synchronize import ( + Semaphore as _Semaphore, +) +from typing import Any + from billiard import einfo as einfo from billiard import exceptions as exceptions +from billiard.connection import Connection +from billiard.context import Process as Process +from billiard.exceptions import ( + SoftTimeLimitExceeded as SoftTimeLimitExceeded, +) +from billiard.exceptions import ( + TimeLimitExceeded as TimeLimitExceeded, +) +from billiard.exceptions import ( + WorkerLostError as WorkerLostError, +) +from billiard.pool import Pool as _Pool +from billiard.process import active_children as active_children +from billiard.process import current_process as current_process + +__all__ = [ + "Array", + "AuthenticationError", + "Barrier", + "BoundedSemaphore", + "BufferTooShort", + "Condition", + "Event", + "JoinableQueue", + "Lock", + "Manager", + "Pipe", + "Pool", + "Process", + "ProcessError", + "Queue", + "RLock", + "RawArray", + "RawValue", + "Semaphore", + "SimpleQueue", + "SoftTimeLimitExceeded", + "TimeLimitExceeded", + "TimeoutError", + "Value", + "WorkerLostError", + "active_children", + "allow_connection_pickling", + "cpu_count", + "current_process", + "forking_enable", + "forking_is_enabled", + "freeze_support", + "get_all_start_methods", + "get_context", + "get_logger", + "get_start_method", + "log_to_stderr", + "set_executable", + "set_forkserver_preload", + "set_start_method", +] + +def Array( + typecode_or_type: str | type[_CData], + size_or_initializer: int | Iterable[Any], + *args: Any, + **kwargs: Any, +) -> _CTypesArray[Any]: ... +def Barrier( + parties: int, action: Callable[[], Any] | None = ..., timeout: float | None = ... +) -> _Barrier: ... +def BoundedSemaphore(value: int = ...) -> _BoundedSemaphore: ... +def Condition(lock: _Lock | _RLock | None = ...) -> _Condition: ... +def Event() -> _Event: ... +def JoinableQueue(maxsize: int = ...) -> _JoinableQueue[Any]: ... +def Lock() -> _Lock: ... +def Manager() -> SyncManager: ... +def Pipe( + duplex: bool = ..., rnonblock: bool = ..., wnonblock: bool = ... +) -> tuple[Connection, Connection]: ... +def Pool( + processes: int | None = ..., + initializer: Callable[..., Any] | None = ..., + initargs: tuple[Any, ...] = ..., + maxtasksperchild: int | None = ..., + timeout: float | None = ..., + soft_timeout: float | None = ..., + lost_worker_timeout: float | None = ..., + max_restarts: int | None = ..., + max_restart_freq: int = ..., + on_process_up: Callable[..., Any] | None = ..., + on_process_down: Callable[..., Any] | None = ..., + on_timeout_set: Callable[..., Any] | None = ..., + on_timeout_cancel: Callable[..., Any] | None = ..., + threads: bool = ..., + semaphore: Any | None = ..., + putlocks: bool = ..., + allow_restart: bool = ..., +) -> _Pool: ... +def Queue(maxsize: int = ...) -> _Queue[Any]: ... +def RLock() -> _RLock: ... +def RawArray( + typecode_or_type: str | type[_CData], size_or_initializer: int | Iterable[Any] +) -> _CTypesArray[Any]: ... +def RawValue(typecode_or_type: str | type[_CData], *args: Any) -> Any: ... +def Semaphore(value: int = ...) -> _Semaphore: ... +def SimpleQueue() -> _SimpleQueue[Any]: ... +def Value( + typecode_or_type: str | type[_CData], *args: Any, **kwargs: Any +) -> SynchronizedBase[Any]: ... +def allow_connection_pickling() -> None: ... +def cpu_count() -> int: ... +def forking_enable(value: bool) -> None: ... +def forking_is_enabled() -> bool: ... +def freeze_support() -> None: ... +def get_all_start_methods() -> list[str]: ... +def get_context(method: str | None = ...) -> BaseContext: ... +def get_logger() -> Logger: ... +def get_start_method(allow_none: bool = ...) -> str | None: ... +def log_to_stderr(level: int | None = ...) -> Logger: ... +def set_executable(executable: str) -> None: ... +def set_forkserver_preload(module_names: list[str]) -> None: ... +def set_start_method(method: str, force: bool = ...) -> None: ... diff --git a/billiard-stubs/allowlist.txt b/billiard-stubs/allowlist.txt new file mode 100644 index 0000000..9e70d2a --- /dev/null +++ b/billiard-stubs/allowlist.txt @@ -0,0 +1,2 @@ +# billiard.popen_spawn_win32 is Windows-only and cannot be tested on Linux +billiard.popen_spawn_win32 diff --git a/billiard-stubs/common.pyi b/billiard-stubs/common.pyi index 4bd64e1..7d1863b 100644 --- a/billiard-stubs/common.pyi +++ b/billiard-stubs/common.pyi @@ -1,10 +1,13 @@ import pickle from signal import _HANDLER, _SIGNUM, Signals +from typing import Any from billiard.exceptions import RestartFreqExceeded as _RestartFreqExceeded pickle_load = pickle.load -pickle_loads = pickle.loads + +def pickle_loads(s: Any, load: Any = ...) -> Any: ... + SIGMAP: dict[Signals, str] TERM_SIGNAL: Signals TERM_SIGNAME: str diff --git a/billiard-stubs/compat.pyi b/billiard-stubs/compat.pyi index 0d13ba2..68ee9ff 100644 --- a/billiard-stubs/compat.pyi +++ b/billiard-stubs/compat.pyi @@ -6,7 +6,9 @@ from typing import SupportsInt, TypeAlias, TypeVar from _typeshed import FileDescriptorLike, ReadableBuffer, StrOrBytesPath -FILENO_ERRORS: tuple[Exception] +FILENO_ERRORS: tuple[ + type[AttributeError], type[ValueError], type[io.UnsupportedOperation] +] __write__ = os.write def send_offset(fd: int, buf: ReadableBuffer, offset: int) -> int: ... @@ -14,9 +16,9 @@ def send_offset(fd: int, buf: ReadableBuffer, offset: int) -> int: ... fsencode = os.fsencode fsdecode = os.fsdecode -MaybeFileNo: TypeAlias = numbers.Integral | io.IOBase +_MaybeFileNo: TypeAlias = numbers.Integral | io.IOBase -def maybe_fileno(f: MaybeFileNo) -> numbers.Integral: ... +def maybe_fileno(f: _MaybeFileNo) -> numbers.Integral: ... def get_fdmax(default: int | None = ...) -> int | None: ... _T = TypeVar("_T") @@ -25,10 +27,10 @@ def uniq(it: Sequence[_T]) -> Iterator[_T]: ... closerange = os.closerange -def close_open_fds(keep: Sequence[MaybeFileNo] | None = ...) -> None: ... +def close_open_fds(keep: Sequence[_MaybeFileNo] | None = ...) -> None: ... def get_errno(exc: Exception | None) -> int: ... def spawnv_passfds( - path: StrOrBytesPath, args: os._ExecVArgs, passfds: Sequence[MaybeFileNo] + path: StrOrBytesPath, args: os._ExecVArgs, passfds: Sequence[_MaybeFileNo] ) -> int: ... def isblocking(handle: FileDescriptorLike) -> bool: ... def setblocking(handle: FileDescriptorLike, blocking: bool) -> None: ... diff --git a/billiard-stubs/connection.pyi b/billiard-stubs/connection.pyi index 9c9641b..d150967 100644 --- a/billiard-stubs/connection.pyi +++ b/billiard-stubs/connection.pyi @@ -1,23 +1,99 @@ -__all__ = ["Listener"] +from collections.abc import Callable, Iterable +from types import TracebackType +from typing import Any -class _SocketContainer: ... +from typing_extensions import Self + +__all__ = ["Client", "Listener", "Pipe", "wait"] + +from socket import socket + +class _SocketContainer: + def __init__(self, sock: socket) -> None: ... class _ConnectionBase: + def __init__( + self, handle: int, readable: bool = ..., writable: bool = ... + ) -> None: ... def __del__(self) -> None: ... def close(self) -> None: ... + def send(self, obj: Any) -> None: ... + def recv(self) -> Any: ... + def poll(self, timeout: float = ...) -> bool: ... + def send_bytes( + self, buf: bytes, offset: int = ..., size: int | None = ... + ) -> None: ... + def recv_bytes(self, maxlength: int | None = ...) -> bytes: ... + def recv_bytes_into(self, buf: bytearray, offset: int = ...) -> int: ... + def send_offset(self, buf: bytes, offset: int) -> None: ... + def setblocking(self, blocking: bool) -> None: ... + @property + def closed(self) -> bool: ... + @property + def readable(self) -> bool: ... + @property + def writable(self) -> bool: ... + def fileno(self) -> int: ... + def __enter__(self) -> Self: ... + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_value: BaseException | None, + exc_tb: TracebackType | None, + ) -> None: ... -class PipeConnection(_ConnectionBase): ... class Connection(_ConnectionBase): ... class Listener: def __init__( self, + address: str | tuple[str, int] | None = ..., + family: str | None = ..., backlog: int = ..., + authkey: bytes | None = ..., ) -> None: ... + def accept(self) -> Connection: ... def close(self) -> None: ... + @property + def address(self) -> str | tuple[str, int]: ... + @property + def last_accepted(self) -> str | tuple[str, int] | None: ... + def __enter__(self) -> Self: ... + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_value: BaseException | None, + exc_tb: TracebackType | None, + ) -> None: ... class SocketListener: + def __init__( + self, + address: str | tuple[str, int], + family: str, + backlog: int = ..., + ) -> None: ... + def accept(self) -> Connection: ... def close(self) -> None: ... -class ConnectionWrapper: ... +class ConnectionWrapper: + def __init__( + self, + conn: Connection, + dumps: Callable[..., bytes], + loads: Callable[..., Any], + ) -> None: ... + def send(self, obj: Any) -> None: ... + def recv(self) -> Any: ... + class XmlListener(Listener): ... + +def Client( + address: str | tuple[str, int], + family: str | None = ..., + authkey: bytes | None = ..., +) -> Connection: ... +def Pipe( + duplex: bool = ..., rnonblock: bool = ..., wnonblock: bool = ... +) -> tuple[Connection, Connection]: ... +def wait(object_list: Iterable[Any], timeout: float | None = ...) -> list[Any]: ... diff --git a/billiard-stubs/context.pyi b/billiard-stubs/context.pyi index e5c7df4..aa5dd38 100644 --- a/billiard-stubs/context.pyi +++ b/billiard-stubs/context.pyi @@ -1,52 +1,164 @@ -from billiard import process -from billiard.exceptions import ( +from collections.abc import Callable, Iterable +from ctypes import Array as _CTypesArray +from ctypes import _CData +from logging import Logger +from multiprocessing import ( AuthenticationError, BufferTooShort, ProcessError, + TimeoutError, +) +from multiprocessing.managers import SyncManager +from multiprocessing.queues import ( + JoinableQueue as _JoinableQueue, +) +from multiprocessing.queues import ( + Queue as _Queue, +) +from multiprocessing.queues import ( + SimpleQueue as _SimpleQueue, +) +from multiprocessing.sharedctypes import SynchronizedBase +from multiprocessing.synchronize import ( + Barrier as _Barrier, +) +from multiprocessing.synchronize import ( + BoundedSemaphore as _BoundedSemaphore, +) +from multiprocessing.synchronize import ( + Condition as _Condition, +) +from multiprocessing.synchronize import ( + Event as _Event, +) +from multiprocessing.synchronize import ( + Lock as _Lock, +) +from multiprocessing.synchronize import ( + RLock as _RLock, +) +from multiprocessing.synchronize import ( + Semaphore as _Semaphore, +) +from typing import Any + +from billiard import process +from billiard.connection import Connection +from billiard.exceptions import ( SoftTimeLimitExceeded, TimeLimitExceeded, - TimeoutError, WorkerLostError, ) +from billiard.pool import Pool as _Pool +from billiard.process import BaseProcess +from typing_extensions import override -__all__ = [ - "W_NO_EXECV", - "AuthenticationError", - "BaseContext", - "BufferTooShort", - "DefaultContext", - "ForkContext", - "ForkProcess", - "ForkServerContext", - "ForkServerProcess", - "Process", - "ProcessError", - "SoftTimeLimitExceeded", - "SpawnContext", - "SpawnProcess", - "TimeLimitExceeded", - "TimeoutError", - "WorkerLostError", - "process", -] +__all__: list[str] = [] W_NO_EXECV: str class BaseContext: - def freeze_support(self) -> None: ... + Process: type[BaseProcess] + AuthenticationError: type[AuthenticationError] + BufferTooShort: type[BufferTooShort] + ProcessError: type[ProcessError] + TimeoutError: type[TimeoutError] + SoftTimeLimitExceeded: type[SoftTimeLimitExceeded] + TimeLimitExceeded: type[TimeLimitExceeded] + WorkerLostError: type[WorkerLostError] + + def Array( + self, + typecode_or_type: str | type[_CData], + size_or_initializer: int | Iterable[Any], + *args: Any, + **kwargs: Any, + ) -> _CTypesArray[Any]: ... + def Barrier( + self, + parties: int, + action: Callable[[], Any] | None = ..., + timeout: float | None = ..., + ) -> _Barrier: ... + def BoundedSemaphore(self, value: int = ...) -> _BoundedSemaphore: ... + def Condition(self, lock: _Lock | _RLock | None = ...) -> _Condition: ... + def Event(self) -> _Event: ... + def JoinableQueue(self, maxsize: int = ...) -> _JoinableQueue[Any]: ... + def Lock(self) -> _Lock: ... + def Manager(self) -> SyncManager: ... + def Pipe( + self, duplex: bool = ..., rnonblock: bool = ..., wnonblock: bool = ... + ) -> tuple[Connection, Connection]: ... + def Pool( + self, + processes: int | None = ..., + initializer: Callable[..., Any] | None = ..., + initargs: tuple[Any, ...] = ..., + maxtasksperchild: int | None = ..., + timeout: float | None = ..., + soft_timeout: float | None = ..., + lost_worker_timeout: float | None = ..., + max_restarts: int | None = ..., + max_restart_freq: int = ..., + on_process_up: Callable[..., Any] | None = ..., + on_process_down: Callable[..., Any] | None = ..., + on_timeout_set: Callable[..., Any] | None = ..., + on_timeout_cancel: Callable[..., Any] | None = ..., + threads: bool = ..., + semaphore: Any | None = ..., + putlocks: bool = ..., + allow_restart: bool = ..., + ) -> _Pool: ... + def Queue(self, maxsize: int = ...) -> _Queue[Any]: ... + def RLock(self) -> _RLock: ... + def RawArray( + self, + typecode_or_type: str | type[_CData], + size_or_initializer: int | Iterable[Any], + ) -> _CTypesArray[Any]: ... + def RawValue(self, typecode_or_type: str | type[_CData], *args: Any) -> Any: ... + def Semaphore(self, value: int = ...) -> _Semaphore: ... + def SimpleQueue(self) -> _SimpleQueue[Any]: ... + def Value( + self, typecode_or_type: str | type[_CData], *args: Any, **kwargs: Any + ) -> SynchronizedBase[Any]: ... + @staticmethod + def active_children(_cleanup: Callable[[], None] = ...) -> list[BaseProcess]: ... def allow_connection_pickling(self) -> None: ... + def cpu_count(self) -> int: ... + @staticmethod + def current_process() -> BaseProcess: ... + def forking_enable(self, value: bool) -> None: ... + def forking_is_enabled(self) -> bool: ... + def freeze_support(self) -> None: ... + def get_context(self, method: str | None = ...) -> BaseContext: ... + def get_logger(self) -> Logger: ... + def get_start_method(self, allow_none: bool = ...) -> str | None: ... + def log_to_stderr(self, level: int | None = ...) -> Logger: ... + def set_executable(self, executable: str) -> None: ... + def set_forkserver_preload(self, module_names: list[str]) -> None: ... + def set_start_method(self, method: str | None = ...) -> None: ... class Process(process.BaseProcess): ... -class DefaultContext(BaseContext): ... + +class DefaultContext(BaseContext): + __all__: list[str] + def __init__(self, context: BaseContext) -> None: ... + def get_all_start_methods(self) -> list[str]: ... + @override + def set_start_method( # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] + self, method: str, force: bool = ... + ) -> None: ... + class ForkProcess(process.BaseProcess): ... class SpawnProcess(process.BaseProcess): ... class ForkServerProcess(process.BaseProcess): ... class ForkContext(BaseContext): - Process = ForkProcess + Process: type[ForkProcess] # pyright: ignore[reportIncompatibleVariableOverride] class SpawnContext(BaseContext): - Process = SpawnProcess + Process: type[SpawnProcess] # pyright: ignore[reportIncompatibleVariableOverride] class ForkServerContext(BaseContext): - Process = ForkServerProcess + Process: type[ForkServerProcess] # pyright: ignore[reportIncompatibleVariableOverride] diff --git a/billiard-stubs/dummy/__init__.pyi b/billiard-stubs/dummy/__init__.pyi index 9d0bebd..71176e2 100644 --- a/billiard-stubs/dummy/__init__.pyi +++ b/billiard-stubs/dummy/__init__.pyi @@ -1,22 +1,31 @@ import threading +from collections.abc import Callable, Iterable, Mapping from queue import Queue as Queue from threading import BoundedSemaphore as BoundedSemaphore + +# Note: Condition is a custom class in billiard.dummy, not threading.Condition from threading import Event as Event from threading import Lock as Lock -from threading import RLock as RLock from threading import Semaphore as Semaphore +from typing import Any +from billiard.connection import Pipe as Pipe from typing_extensions import override __all__ = [ "BoundedSemaphore", + "Condition", "Event", "JoinableQueue", "Lock", + "Manager", + "Pipe", + "Pool", "Process", "Queue", "RLock", "Semaphore", + "active_children", "current_process", "freeze_support", ] @@ -24,13 +33,39 @@ __all__ = [ class DummyProcess(threading.Thread): def __init__( self, + group: None = ..., + target: Callable[..., object] | None = ..., + name: str | None = ..., + args: Iterable[Any] = ..., + kwargs: Mapping[str, Any] = ..., ) -> None: ... @override def start(self) -> None: ... + @property + def exitcode(self) -> int | None: ... Process = DummyProcess current_process = threading.current_thread def freeze_support() -> None: ... +def active_children() -> list[DummyProcess]: ... +def Manager() -> Any: ... +def Pool( + processes: int | None = ..., + initializer: Callable[..., object] | None = ..., + initargs: Iterable[Any] = ..., +) -> Any: ... +def RLock(*args: Any, **kwargs: Any) -> threading.RLock: ... + +class Condition: + def __init__(self, lock: Any = ...) -> None: ... + def __enter__(self) -> bool: ... + def __exit__(self, *args: object) -> None: ... + def wait(self, timeout: float | None = ...) -> bool: ... + def wait_for( + self, predicate: Callable[[], bool], timeout: float | None = ... + ) -> bool: ... + def notify(self, n: int = ...) -> None: ... + def notify_all(self) -> None: ... JoinableQueue = Queue diff --git a/billiard-stubs/dummy/connection.pyi b/billiard-stubs/dummy/connection.pyi new file mode 100644 index 0000000..1af1467 --- /dev/null +++ b/billiard-stubs/dummy/connection.pyi @@ -0,0 +1,28 @@ +from queue import Queue +from typing import Any + +from typing_extensions import Self + +__all__ = ["Client", "Listener", "Pipe"] + +class Connection: + def __init__(self, _in: Queue[Any], _out: Queue[Any]) -> None: ... + def poll(self, timeout: float = ...) -> bool: ... + def close(self) -> None: ... + +class Listener: + def __init__( + self, + address: Any = ..., + family: str | None = ..., + backlog: int = ..., + ) -> None: ... + def accept(self) -> Connection: ... + def close(self) -> None: ... + def __enter__(self) -> Self: ... + def __exit__(self, *exc_info: object) -> None: ... + @property + def address(self) -> Any: ... + +def Client(address: Any) -> Connection: ... +def Pipe(duplex: bool = ...) -> tuple[Connection, Connection]: ... diff --git a/billiard-stubs/einfo.pyi b/billiard-stubs/einfo.pyi index 316beae..2d484b7 100644 --- a/billiard-stubs/einfo.pyi +++ b/billiard-stubs/einfo.pyi @@ -1 +1,42 @@ -class ExceptionInfo: ... +from types import TracebackType +from typing import Any, TypeAlias + +__all__ = ["ExceptionInfo", "Traceback"] + +class _Code: + def __init__(self, code: Any) -> None: ... + @property + def co_positions(self) -> Any: ... + +class _Frame: + Code = _Code + + def __init__(self, frame: Any) -> None: ... + @property + def co_positions(self) -> Any: ... + +class Traceback: + Frame = _Frame + Code = _Code + + def __init__( + self, tb: TracebackType | None, max_frames: int = ..., depth: int = ... + ) -> None: ... + +_ExcInfo: TypeAlias = tuple[type[BaseException], BaseException, TracebackType | None] + +class ExceptionInfo: + exception: BaseException | None + internal: bool + tb: TracebackType | None + traceback: str | None + + def __init__( + self, + exc_info: _ExcInfo | None = ..., + internal: bool = ..., + ) -> None: ... + @property + def type(self) -> type[BaseException] | None: ... # ty: ignore[invalid-type-form] + @property + def exc_info(self) -> _ExcInfo | None: ... diff --git a/billiard-stubs/exceptions.pyi b/billiard-stubs/exceptions.pyi index d086b70..f3c4e6f 100644 --- a/billiard-stubs/exceptions.pyi +++ b/billiard-stubs/exceptions.pyi @@ -1,22 +1,7 @@ -from multiprocessing import ( - AuthenticationError, - BufferTooShort, - ProcessError, - TimeoutError, -) - -__all__ = [ - "AuthenticationError", - "BufferTooShort", - "CoroStop", - "ProcessError", - "RestartFreqExceeded", - "SoftTimeLimitExceeded", - "Terminated", - "TimeLimitExceeded", - "TimeoutError", - "WorkerLostError", -] +from multiprocessing import AuthenticationError as AuthenticationError +from multiprocessing import BufferTooShort as BufferTooShort +from multiprocessing import ProcessError as ProcessError +from multiprocessing import TimeoutError as TimeoutError class TimeLimitExceeded(Exception): ... class SoftTimeLimitExceeded(Exception): ... diff --git a/billiard-stubs/forkserver.pyi b/billiard-stubs/forkserver.pyi new file mode 100644 index 0000000..6188611 --- /dev/null +++ b/billiard-stubs/forkserver.pyi @@ -0,0 +1,13 @@ +from collections.abc import Sequence + +__all__ = [ + "connect_to_new_process", + "ensure_running", + "get_inherited_fds", + "set_forkserver_preload", +] + +def connect_to_new_process(fds: Sequence[int]) -> tuple[int, int]: ... +def ensure_running() -> None: ... +def get_inherited_fds() -> list[int] | None: ... +def set_forkserver_preload(modules_names: list[str]) -> None: ... diff --git a/billiard-stubs/heap.pyi b/billiard-stubs/heap.pyi new file mode 100644 index 0000000..36c5754 --- /dev/null +++ b/billiard-stubs/heap.pyi @@ -0,0 +1,7 @@ +__all__ = ["BufferWrapper"] + +class BufferWrapper: + def __init__(self, size: int) -> None: ... + def create_memoryview(self) -> memoryview: ... + def get_address(self) -> int: ... + def get_size(self) -> int: ... diff --git a/billiard-stubs/managers.pyi b/billiard-stubs/managers.pyi new file mode 100644 index 0000000..8b961ab --- /dev/null +++ b/billiard-stubs/managers.pyi @@ -0,0 +1,81 @@ +from multiprocessing.context import BaseContext +from types import TracebackType +from typing import Any + +from typing_extensions import Self + +__all__ = ["BaseManager", "BaseProxy", "SyncManager", "Token"] + +class Token: + typeid: str | None + address: tuple[str, int] | str | None + id: str | None + def __init__( + self, + typeid: str | None, + address: tuple[str, int] | str | None, + id: str | None, + ) -> None: ... + +class BaseProxy: + def __init__( + self, + token: Any, + serializer: str, + manager: Any = ..., + authkey: str | bytes | None = ..., + exposed: Any = ..., + incref: bool = ..., + ) -> None: ... + def __deepcopy__(self, memo: dict[int, Any]) -> BaseProxy: ... + +class BaseManager: + def __init__( + self, + address: str | tuple[str, int] | None = ..., + authkey: bytes | None = ..., + serializer: str = ..., + ctx: BaseContext | None = ..., + ) -> None: ... + def start( + self, initializer: Any = ..., initargs: tuple[Any, ...] = ... + ) -> None: ... + def get_server(self) -> Any: ... + def connect(self) -> None: ... + def join(self, timeout: float | None = ...) -> None: ... + @classmethod + def register( + cls, + typeid: str, + callable: Any = ..., + proxytype: type[Any] | None = ..., + exposed: Any = ..., + method_to_typeid: dict[str, str] | None = ..., + create_method: bool = ..., + ) -> None: ... + @property + def address(self) -> tuple[str, int] | str | None: ... + def __enter__(self) -> Self: ... + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> None: ... + +class SyncManager(BaseManager): + def Barrier(self, *args: Any, **kwds: Any) -> Any: ... + def BoundedSemaphore(self, *args: Any, **kwds: Any) -> Any: ... + def Condition(self, *args: Any, **kwds: Any) -> Any: ... + def Event(self, *args: Any, **kwds: Any) -> Any: ... + def JoinableQueue(self, *args: Any, **kwds: Any) -> Any: ... + def Lock(self, *args: Any, **kwds: Any) -> Any: ... + def Namespace(self, *args: Any, **kwds: Any) -> Any: ... + def Pool(self, *args: Any, **kwds: Any) -> Any: ... + def Queue(self, *args: Any, **kwds: Any) -> Any: ... + def RLock(self, *args: Any, **kwds: Any) -> Any: ... + def Semaphore(self, *args: Any, **kwds: Any) -> Any: ... + def Value(self, *args: Any, **kwds: Any) -> Any: ... + def Array(self, *args: Any, **kwds: Any) -> Any: ... + def dict(self, *args: Any, **kwds: Any) -> Any: ... + def list(self, *args: Any, **kwds: Any) -> Any: ... diff --git a/billiard-stubs/pool.pyi b/billiard-stubs/pool.pyi index 30e4803..288a1ba 100644 --- a/billiard-stubs/pool.pyi +++ b/billiard-stubs/pool.pyi @@ -3,80 +3,14 @@ from typing import Any from billiard.common import ( TERM_SIGNAL, - human_status, - pickle_loads, - reset_signals, - restart_state, ) -from billiard.compat import get_errno, mem_rss, send_offset -from billiard.dummy import DummyProcess, Process -from billiard.einfo import ExceptionInfo +from billiard.dummy import DummyProcess from billiard.exceptions import ( - CoroStop, - RestartFreqExceeded, SoftTimeLimitExceeded, - Terminated, - TimeLimitExceeded, - TimeoutError, - WorkerLostError, ) -from billiard.util import debug, warning -from typing_extensions import override - -__all__ = [ - "ACK", - "CLOSE", - "DEATH", - "EX_FAILURE", - "EX_OK", - "EX_RECYCLE", - "GUARANTEE_MESSAGE_CONSUMPTION_RETRY_INTERVAL", - "GUARANTEE_MESSAGE_CONSUMPTION_RETRY_LIMIT", - "LOST_WORKER_TIMEOUT", - "MAXMEM_USED_FMT", - "NACK", - "READY", - "RUN", - "SIGKILL", - "TASK", - "TERMINATE", - "TERM_SIGNAL", - "ApplyResult", - "CoroStop", - "DummyProcess", - "ExceptionInfo", - "IMapIterator", - "IMapUnorderedIterator", - "LaxBoundedSemaphore", - "Lock", - "MapResult", - "MaybeEncodingError", - "Pool", - "PoolThread", - "Process", - "RestartFreqExceeded", - "ResultHandler", - "SoftTimeLimitExceeded", - "Supervisor", - "TaskHandler", - "Terminated", - "ThreadPool", - "TimeLimitExceeded", - "TimeoutError", - "TimeoutHandler", - "Worker", - "WorkerLostError", - "WorkersJoined", - "debug", - "get_errno", - "human_status", - "mem_rss", - "pickle_loads", - "reset_signals", - "restart_state", - "send_offset", - "warning", -] +from typing_extensions import Self, override + +# Note: __all__ is not present at runtime MAXMEM_USED_FMT: str SIGKILL = TERM_SIGNAL @@ -95,12 +29,25 @@ LOST_WORKER_TIMEOUT: float GUARANTEE_MESSAGE_CONSUMPTION_RETRY_LIMIT: int GUARANTEE_MESSAGE_CONSUMPTION_RETRY_INTERVAL: float Lock = threading.Lock +PY3: bool +SIG_SOFT_TIMEOUT: int +TIMEOUT_MAX: float + +def error(msg: str, *args: Any, **kwargs: Any) -> None: ... + +job_counter: Any + +def mapstar(args: Any) -> Any: ... +def starmapstar(args: Any) -> Any: ... +def soft_timeout_sighandler(signum: int, frame: Any) -> None: ... +def stop_if_not_current(thread: Any, timeout: float | None = ...) -> None: ... class LaxBoundedSemaphore(threading.Semaphore): + def __init__(self, value: int = ..., verbose: Any = ...) -> None: ... def shrink(self) -> None: ... def grow(self) -> None: ... @override - def release(self, n: int = ...) -> None: ... + def release(self) -> None: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] def clear(self) -> None: ... class MaybeEncodingError(Exception): @@ -109,33 +56,121 @@ class MaybeEncodingError(Exception): class WorkersJoined(Exception): ... class Worker: + def __init__( + self, + inq: Any, + outq: Any, + synq: Any = ..., + initializer: Any = ..., + initargs: tuple[Any, ...] = ..., + maxtasks: int | None = ..., + sentinel: Any = ..., + on_exit: Any = ..., + sigprotection: bool = ..., + wrap_exception: bool = ..., + max_memory_per_child: int | None = ..., + on_ready_counter: Any = ..., + ) -> None: ... + def __call__(self) -> None: ... def after_fork(self) -> None: ... + def contribute_to_object(self, obj: Any) -> None: ... + def on_loop_start(self, pid: int) -> None: ... + def prepare_result(self, result: Any) -> Any: ... + def workloop( + self, debug: Any = ..., now: Any = ..., pid: int | None = ... + ) -> None: ... class PoolThread(DummyProcess): daemon: bool + def __init__(self, *args: Any, **kwargs: Any) -> None: ... + @override + def start(self, *args: Any, **kwargs: Any) -> None: ... + def stop(self, timeout: float | None = ...) -> None: ... def on_stop_not_started(self) -> None: ... def terminate(self) -> None: ... def close(self) -> None: ... class Supervisor(PoolThread): + def __init__(self, pool: Any) -> None: ... def body(self) -> None: ... class TaskHandler(PoolThread): + def __init__( + self, taskqueue: Any, put: Any, outqueue: Any, pool: Any, cache: Any + ) -> None: ... def body(self) -> None: ... def tell_others(self) -> None: ... @override def on_stop_not_started(self) -> None: ... class TimeoutHandler(PoolThread): + def __init__( + self, processes: Any, cache: Any, t_soft: float | None, t_hard: float | None + ) -> None: ... def body(self) -> None: ... + def handle_event(self, *args: Any) -> None: ... + def handle_timeouts(self) -> None: ... + def on_soft_timeout(self, job: Any) -> None: ... + def on_hard_timeout(self, job: Any) -> None: ... class ResultHandler(PoolThread): + def __init__( + self, + outqueue: Any, + get: Any, + cache: Any, + poll: Any, + join_exited_workers: Any, + putlock: Any, + restart_state: Any, + check_timeouts: Any, + on_job_ready: Any, + on_ready_counters: Any = ..., + ) -> None: ... @override def on_stop_not_started(self) -> None: ... def body(self) -> None: ... + def handle_event(self, fileno: int | None = ..., events: Any = ...) -> None: ... def finish_at_shutdown(self, handle_timeouts: bool = ...) -> None: ... class Pool: + def Process(self, *args: Any, **kwds: Any) -> Any: ... + Worker: type[Worker] + def WorkerProcess(self, worker: Any) -> Any: ... + Supervisor: type[Supervisor] + TaskHandler: type[TaskHandler] + TimeoutHandler: type[TimeoutHandler] + ResultHandler: type[ResultHandler] + SoftTimeLimitExceeded: type[SoftTimeLimitExceeded] + + def __init__( + self, + processes: int | None = ..., + initializer: Any = ..., + initargs: tuple[Any, ...] = ..., + maxtasksperchild: int | None = ..., + timeout: float | None = ..., + soft_timeout: float | None = ..., + lost_worker_timeout: float | None = ..., + max_restarts: int | None = ..., + max_restart_freq: int = ..., + on_process_up: Any = ..., + on_process_down: Any = ..., + on_timeout_set: Any = ..., + on_timeout_cancel: Any = ..., + threads: bool = ..., + semaphore: Any = ..., + putlocks: bool = ..., + allow_restart: bool = ..., + synack: bool = ..., + on_process_exit: Any = ..., + context: Any = ..., + max_memory_per_child: int | None = ..., + enable_timeouts: bool = ..., + **kwargs: Any, + ) -> None: ... + def __enter__(self) -> Self: ... + def __exit__(self, *exc_info: object) -> None: ... def shrink(self, n: int = ...) -> None: ... def grow(self, n: int = ...) -> None: ... def maintain_pool(self) -> None: ... @@ -145,15 +180,133 @@ class Pool: def terminate(self) -> None: ... def join(self) -> None: ... def restart(self) -> None: ... + def cpu_count(self) -> int: ... + def create_result_handler(self, **extra_kwargs: Any) -> Any: ... + def did_start_ok(self) -> bool: ... + def get_process_queues(self) -> Any: ... + def handle_result_event(self, *args: Any) -> None: ... + def apply( + self, func: Any, args: tuple[Any, ...] = ..., kwds: dict[str, Any] = ... + ) -> Any: ... + def apply_async( + self, + func: Any, + args: tuple[Any, ...] = ..., + kwds: dict[str, Any] = ..., + callback: Any = ..., + error_callback: Any = ..., + accept_callback: Any = ..., + timeout_callback: Any = ..., + waitforslot: bool | None = ..., + soft_timeout: float | None = ..., + timeout: float | None = ..., + lost_worker_timeout: float | None = ..., + callbacks_propagate: tuple[Any, ...] = ..., + correlation_id: Any = ..., + ) -> ApplyResult: ... + def imap( + self, + func: Any, + iterable: Any, + chunksize: int = ..., + lost_worker_timeout: float | None = ..., + ) -> IMapIterator: ... + def imap_unordered( + self, + func: Any, + iterable: Any, + chunksize: int = ..., + lost_worker_timeout: float | None = ..., + ) -> IMapUnorderedIterator: ... + def map( + self, func: Any, iterable: Any, chunksize: int | None = ... + ) -> list[Any]: ... + def map_async( + self, + func: Any, + iterable: Any, + chunksize: int | None = ..., + callback: Any = ..., + error_callback: Any = ..., + ) -> MapResult: ... + def starmap( + self, func: Any, iterable: Any, chunksize: int | None = ... + ) -> list[Any]: ... + def starmap_async( + self, + func: Any, + iterable: Any, + chunksize: int | None = ..., + callback: Any = ..., + error_callback: Any = ..., + ) -> MapResult: ... + def mark_as_worker_lost(self, job: Any, exitcode: int) -> None: ... + def on_grow(self, n: int) -> None: ... + def on_job_process_down(self, job: Any, pid_gone: bool) -> None: ... + def on_job_process_lost(self, job: Any, pid: int, exitcode: int) -> None: ... + def on_job_ready(self, job: Any, i: int, obj: Any, inqW_fd: Any) -> None: ... + def on_partial_read(self, job: Any, worker: Any) -> None: ... + def on_shrink(self, n: int) -> None: ... + def process_flush_queues(self, worker: Any) -> None: ... + @property + def process_sentinels(self) -> list[Any]: ... + def send_ack(self, response: Any, job: Any, i: int, fd: Any) -> None: ... + def terminate_job(self, pid: int, sig: int | None = ...) -> None: ... class ApplyResult: + def __init__( + self, + cache: Any, + callback: Any, + accept_callback: Any = ..., + timeout_callback: Any = ..., + error_callback: Any = ..., + soft_timeout: float | None = ..., + timeout: float | None = ..., + lost_worker_timeout: float = ..., + on_timeout_set: Any = ..., + on_timeout_cancel: Any = ..., + callbacks_propagate: tuple[Any, ...] = ..., + send_ack: Any = ..., + correlation_id: Any = ..., + ) -> None: ... + def ready(self) -> bool: ... + def accepted(self) -> bool: ... + def successful(self) -> bool: ... + def get(self, timeout: float | None = ...) -> Any: ... + def wait(self, timeout: float | None = ...) -> bool: ... + def terminate(self, signum: int) -> None: ... + def worker_pids(self) -> list[int]: ... + def safe_apply_callback(self, fun: Any, *args: Any, **kwargs: Any) -> None: ... def discard(self) -> None: ... def handle_timeout(self, soft: bool = ...) -> None: ... -class MapResult(ApplyResult): ... -class IMapIterator: ... +class MapResult(ApplyResult): + def __init__( + self, + cache: Any, + chunksize: int, + length: int, + callback: Any, + error_callback: Any, + ) -> None: ... + +class IMapIterator: + def __init__(self, cache: Any, lost_worker_timeout: float = ...) -> None: ... + def __iter__(self) -> IMapIterator: ... + def __next__(self, timeout: float | None = ...) -> Any: ... + def next(self, timeout: float | None = ...) -> Any: ... + def ready(self) -> bool: ... + def worker_pids(self) -> list[int]: ... + class IMapUnorderedIterator(IMapIterator): ... class ThreadPool(Pool): - Process = DummyProcess - def __init__(self) -> None: ... + Process = DummyProcess # pyright: ignore[reportAssignmentType] + DummyProcess: type[DummyProcess] + def __init__( + self, + processes: int | None = ..., + initializer: Any = ..., + initargs: tuple[Any, ...] = ..., + ) -> None: ... diff --git a/billiard-stubs/popen_fork.pyi b/billiard-stubs/popen_fork.pyi new file mode 100644 index 0000000..839a86f --- /dev/null +++ b/billiard-stubs/popen_fork.pyi @@ -0,0 +1,16 @@ +from billiard.process import BaseProcess + +__all__ = ["Popen"] + +class Popen: + method: str + returncode: int | None + pid: int + sentinel: int | None + + def __init__(self, process_obj: BaseProcess) -> None: ... + def duplicate_for_child(self, fd: int) -> int: ... + def poll(self, flag: int = ...) -> int | None: ... + def wait(self, timeout: float | None = ...) -> int | None: ... + def terminate(self) -> None: ... + def close(self) -> None: ... diff --git a/billiard-stubs/popen_forkserver.pyi b/billiard-stubs/popen_forkserver.pyi new file mode 100644 index 0000000..ccec934 --- /dev/null +++ b/billiard-stubs/popen_forkserver.pyi @@ -0,0 +1,19 @@ +from billiard.process import BaseProcess + +__all__ = ["Popen"] + +class Popen: + method: str + returncode: int | None + pid: int + sentinel: int | None + + class DupFd: + def __init__(self, ind: int) -> None: ... + def detach(self) -> int: ... + + def __init__(self, process_obj: BaseProcess) -> None: ... + def duplicate_for_child(self, fd: int) -> int: ... + def poll(self, flag: int = ...) -> int | None: ... + def wait(self, timeout: float | None = ...) -> int | None: ... + def terminate(self) -> None: ... diff --git a/billiard-stubs/popen_spawn_posix.pyi b/billiard-stubs/popen_spawn_posix.pyi new file mode 100644 index 0000000..be8cee9 --- /dev/null +++ b/billiard-stubs/popen_spawn_posix.pyi @@ -0,0 +1,19 @@ +from billiard.process import BaseProcess + +__all__ = ["Popen"] + +class Popen: + method: str + returncode: int | None + pid: int + sentinel: int | None + + class DupFd: + def __init__(self, fd: int) -> None: ... + def detach(self) -> int: ... + + def __init__(self, process_obj: BaseProcess) -> None: ... + def duplicate_for_child(self, fd: int) -> int: ... + def poll(self, flag: int = ...) -> int | None: ... + def wait(self, timeout: float | None = ...) -> int | None: ... + def terminate(self) -> None: ... diff --git a/billiard-stubs/popen_spawn_win32.pyi b/billiard-stubs/popen_spawn_win32.pyi new file mode 100644 index 0000000..e99ddd4 --- /dev/null +++ b/billiard-stubs/popen_spawn_win32.pyi @@ -0,0 +1,21 @@ +# This module is Windows-only and requires msvcrt + +from billiard.process import BaseProcess + +__all__ = ["Popen"] + +class Popen: + method: str + returncode: int | None + pid: int + sentinel: int | None + + class DupFd: + def __init__(self, fd: int) -> None: ... + def detach(self) -> int: ... + + def __init__(self, process_obj: BaseProcess) -> None: ... + def duplicate_for_child(self, fd: int) -> int: ... + def poll(self, flag: int = ...) -> int | None: ... + def wait(self, timeout: float | None = ...) -> int | None: ... + def terminate(self) -> None: ... diff --git a/billiard-stubs/process.pyi b/billiard-stubs/process.pyi index e6def8d..63a7a64 100644 --- a/billiard-stubs/process.pyi +++ b/billiard-stubs/process.pyi @@ -9,6 +9,13 @@ class BaseProcess: name: str def __init__( self, + group: None = ..., + target: Callable[..., object] | None = ..., + name: str | None = ..., + args: tuple[object, ...] = ..., + kwargs: dict[str, object] = ..., + daemon: bool | None = ..., + **_kw: object, ) -> None: ... def run(self) -> None: ... def start(self) -> None: ... diff --git a/billiard-stubs/queues.pyi b/billiard-stubs/queues.pyi new file mode 100644 index 0000000..b1c8e21 --- /dev/null +++ b/billiard-stubs/queues.pyi @@ -0,0 +1,34 @@ +from queue import Empty as Empty +from queue import Full as Full +from typing import Any, Generic, TypeVar + +__all__ = ["JoinableQueue", "Queue", "SimpleQueue"] + +_T = TypeVar("_T") + +class Queue(Generic[_T]): + def __init__(self, maxsize: int = ..., *args: Any, **kwargs: Any) -> None: ... + def get(self, block: bool = ..., timeout: float | None = ...) -> _T: ... + def put(self, obj: _T, block: bool = ..., timeout: float | None = ...) -> None: ... + def get_nowait(self) -> _T: ... + def put_nowait(self, obj: _T) -> None: ... + def empty(self) -> bool: ... + def full(self) -> bool: ... + def qsize(self) -> int: ... + def close(self) -> None: ... + def join_thread(self) -> None: ... + def cancel_join_thread(self) -> None: ... + +class JoinableQueue(Queue[_T]): + def __init__(self, maxsize: int = ..., *args: Any, **kwargs: Any) -> None: ... + def task_done(self) -> None: ... + def join(self) -> None: ... + +class SimpleQueue(Generic[_T]): + def __init__(self, *args: Any, **kwargs: Any) -> None: ... + def get(self) -> _T: ... + def put(self, obj: _T) -> None: ... + def empty(self) -> bool: ... + def close(self) -> None: ... + def get_payload(self) -> Any: ... + def send_payload(self, value: Any) -> None: ... diff --git a/billiard-stubs/reduction.pyi b/billiard-stubs/reduction.pyi new file mode 100644 index 0000000..b9762f8 --- /dev/null +++ b/billiard-stubs/reduction.pyi @@ -0,0 +1,24 @@ +import pickle +from collections.abc import Callable +from typing import Any + +__all__ = [ + "DupFd", + "ForkingPickler", + "dump", + "recv_handle", + "recvfds", + "register", + "send_handle", + "sendfds", +] + +ForkingPickler: type[pickle.Pickler] + +def dump(obj: Any, file: Any, protocol: int | None = ...) -> None: ... +def register(type: type, reduce: Callable[[Any], Any]) -> None: ... +def DupFd(fd: int) -> Any: ... +def sendfds(sock: Any, fds: list[int]) -> None: ... +def recvfds(sock: Any, size: int) -> list[int]: ... +def send_handle(conn: Any, handle: int, destination_pid: int) -> None: ... +def recv_handle(conn: Any) -> int: ... diff --git a/billiard-stubs/resource_sharer.pyi b/billiard-stubs/resource_sharer.pyi new file mode 100644 index 0000000..c991d0e --- /dev/null +++ b/billiard-stubs/resource_sharer.pyi @@ -0,0 +1,7 @@ +__all__ = ["DupFd", "stop"] + +class DupFd: + def __init__(self, fd: int) -> None: ... + def detach(self) -> int: ... + +def stop(timeout: float | None = ...) -> None: ... diff --git a/billiard-stubs/semaphore_tracker.pyi b/billiard-stubs/semaphore_tracker.pyi new file mode 100644 index 0000000..af42a7f --- /dev/null +++ b/billiard-stubs/semaphore_tracker.pyi @@ -0,0 +1,6 @@ +__all__ = ["ensure_running", "register", "unregister"] + +def ensure_running() -> None: ... +def getfd() -> int: ... +def register(name: str) -> None: ... +def unregister(name: str) -> None: ... diff --git a/billiard-stubs/sharedctypes.pyi b/billiard-stubs/sharedctypes.pyi new file mode 100644 index 0000000..be8a645 --- /dev/null +++ b/billiard-stubs/sharedctypes.pyi @@ -0,0 +1,8 @@ +__all__ = ["Array", "RawArray", "RawValue", "Value", "copy", "synchronized"] + +from multiprocessing.sharedctypes import Array as Array +from multiprocessing.sharedctypes import RawArray as RawArray +from multiprocessing.sharedctypes import RawValue as RawValue +from multiprocessing.sharedctypes import Value as Value +from multiprocessing.sharedctypes import copy as copy +from multiprocessing.sharedctypes import synchronized as synchronized diff --git a/billiard-stubs/spawn.pyi b/billiard-stubs/spawn.pyi new file mode 100644 index 0000000..724a0c2 --- /dev/null +++ b/billiard-stubs/spawn.pyi @@ -0,0 +1,19 @@ +from typing import Any + +__all__ = [ + "_main", + "freeze_support", + "get_command_line", + "get_executable", + "get_preparation_data", + "import_main_path", + "set_executable", +] + +def get_command_line(**kwds: Any) -> list[str]: ... +def get_executable() -> str: ... +def get_preparation_data(name: str) -> dict[str, Any]: ... +def import_main_path(main_path: str) -> None: ... +def set_executable(exe: str) -> None: ... +def freeze_support() -> None: ... +def _main(fd: int) -> None: ... diff --git a/billiard-stubs/synchronize.pyi b/billiard-stubs/synchronize.pyi new file mode 100644 index 0000000..91bf859 --- /dev/null +++ b/billiard-stubs/synchronize.pyi @@ -0,0 +1,61 @@ +from collections.abc import Callable +from multiprocessing.context import BaseContext + +__all__ = ["BoundedSemaphore", "Condition", "Event", "Lock", "RLock", "Semaphore"] + +class Semaphore: + def __init__(self, value: int = ..., ctx: BaseContext | None = ...) -> None: ... + def __enter__(self) -> bool: ... + def __exit__(self, *args: object) -> None: ... + def get_value(self) -> int: ... + +class BoundedSemaphore(Semaphore): + def __init__(self, value: int = ..., ctx: BaseContext | None = ...) -> None: ... + +class Lock: + def __init__(self, ctx: BaseContext | None = ...) -> None: ... + def __enter__(self) -> bool: ... + def __exit__(self, *args: object) -> None: ... + +class RLock: + def __init__(self, ctx: BaseContext | None = ...) -> None: ... + def __enter__(self) -> bool: ... + def __exit__(self, *args: object) -> None: ... + +class Condition: + def __init__( + self, lock: Lock | RLock | None = ..., ctx: BaseContext | None = ... + ) -> None: ... + def notify(self) -> None: ... + def notify_all(self) -> None: ... + def wait(self, timeout: float | None = ...) -> bool: ... + def wait_for( + self, predicate: Callable[[], bool], timeout: float | None = ... + ) -> bool: ... + def __enter__(self) -> bool: ... + def __exit__(self, *args: object) -> None: ... + +class Event: + def __init__(self, ctx: BaseContext | None = ...) -> None: ... + def is_set(self) -> bool: ... + def set(self) -> None: ... + def clear(self) -> None: ... + def wait(self, timeout: float | None = ...) -> bool: ... + +class Barrier: + def __init__( + self, + parties: int, + action: Callable[[], object] | None = ..., + timeout: float | None = ..., + ctx: BaseContext | None = ..., + ) -> None: ... + def wait(self, timeout: float | None = ...) -> int: ... + def reset(self) -> None: ... + def abort(self) -> None: ... + @property + def parties(self) -> int: ... + @property + def n_waiting(self) -> int: ... + @property + def broken(self) -> bool: ... diff --git a/billiard-stubs/util.pyi b/billiard-stubs/util.pyi index 899e7cd..ccf292a 100644 --- a/billiard-stubs/util.pyi +++ b/billiard-stubs/util.pyi @@ -1,12 +1,24 @@ from logging import Logger, _Level +from multiprocessing.util import Finalize as Finalize +from multiprocessing.util import ForkAwareLocal as ForkAwareLocal +from multiprocessing.util import ForkAwareThreadLock as ForkAwareThreadLock +from multiprocessing.util import get_temp_dir as get_temp_dir +from multiprocessing.util import is_exiting as is_exiting +from multiprocessing.util import register_after_fork as register_after_fork __all__ = [ "SUBDEBUG", "SUBWARNING", + "Finalize", + "ForkAwareLocal", + "ForkAwareThreadLock", "debug", "get_logger", + "get_temp_dir", "info", + "is_exiting", "log_to_stderr", + "register_after_fork", "sub_debug", "sub_warning", ] diff --git a/vine-stubs/__init__.pyi b/vine-stubs/__init__.pyi index 67dcab0..ebe2968 100644 --- a/vine-stubs/__init__.pyi +++ b/vine-stubs/__init__.pyi @@ -1,3 +1,37 @@ +from vine.abstract import Thenable as Thenable +from vine.funtools import ( + ensure_promise as ensure_promise, +) +from vine.funtools import ( + maybe_promise as maybe_promise, +) +from vine.funtools import ( + ppartial as ppartial, +) +from vine.funtools import ( + preplace as preplace, +) +from vine.funtools import ( + starpromise as starpromise, +) +from vine.funtools import ( + transform as transform, +) +from vine.funtools import ( + wrap as wrap, +) from vine.promises import promise as promise +from vine.synchronization import barrier as barrier -__all__ = ["promise"] +__all__ = [ + "Thenable", + "barrier", + "ensure_promise", + "maybe_promise", + "ppartial", + "preplace", + "promise", + "starpromise", + "transform", + "wrap", +] diff --git a/vine-stubs/abstract.pyi b/vine-stubs/abstract.pyi index e69de29..fa25e9c 100644 --- a/vine-stubs/abstract.pyi +++ b/vine-stubs/abstract.pyi @@ -0,0 +1,27 @@ +from abc import ABC, abstractmethod +from collections.abc import Callable +from types import TracebackType +from typing import Any + +class Thenable(ABC): + @abstractmethod + def __call__(self, *args: Any, **kwargs: Any) -> Any: ... + @abstractmethod + def cancel(self) -> None: ... + @classmethod + def register(cls, other: type[Any]) -> type[Any]: ... + @abstractmethod + def then( + self, + on_success: Callable[..., Any], + on_error: Callable[..., Any] | None = ..., + ) -> Thenable: ... + @abstractmethod + def throw( + self, + exc: BaseException | None = ..., + tb: TracebackType | None = ..., + propagate: bool = ..., + ) -> None: ... + +__all__ = ["Thenable"] diff --git a/vine-stubs/funtools.pyi b/vine-stubs/funtools.pyi index e69de29..7a187a2 100644 --- a/vine-stubs/funtools.pyi +++ b/vine-stubs/funtools.pyi @@ -0,0 +1,29 @@ +from collections.abc import Callable +from typing import Any + +from vine.promises import promise + +def maybe_promise(p: Any) -> promise | None: ... +def ensure_promise(p: Any) -> promise: ... +def ppartial(p: promise, *args: Any, **kwargs: Any) -> promise: ... +def preplace(p: promise, *args: Any, **kwargs: Any) -> promise: ... +def ready_promise(callback: Callable[..., Any] | None = ..., *args: Any) -> promise: ... +def starpromise(fun: Callable[..., Any], *args: Any, **kwargs: Any) -> promise: ... +def transform( + filter_: Callable[..., Any], + callback: Callable[..., Any], + *filter_args: Any, + **filter_kwargs: Any, +) -> promise: ... +def wrap(p: Any) -> promise: ... + +__all__ = [ + "ensure_promise", + "maybe_promise", + "ppartial", + "preplace", + "ready_promise", + "starpromise", + "transform", + "wrap", +] diff --git a/vine-stubs/promises.pyi b/vine-stubs/promises.pyi index 1b4e0e9..4418681 100644 --- a/vine-stubs/promises.pyi +++ b/vine-stubs/promises.pyi @@ -1 +1,53 @@ -class promise: ... +from collections.abc import Callable +from types import TracebackType +from typing import Any + +from typing_extensions import override +from vine.abstract import Thenable + +class promise(Thenable): + args: tuple[Any, ...] | None + kwargs: dict[str, Any] | None + fun: Callable[..., Any] | None + on_error: Callable[..., Any] | None + weak: bool + + @property + def listeners(self) -> list[Callable[..., Any]]: ... + ignore_result: bool + cancelled: bool + ready: bool + failed: bool + value: Any + reason: BaseException | None + + def __init__( + self, + fun: Callable[..., Any] | None = ..., + args: tuple[Any, ...] | None = ..., + kwargs: dict[str, Any] | None = ..., + callback: Callable[..., Any] | None = ..., + on_error: Callable[..., Any] | None = ..., + weak: bool = ..., + ignore_result: bool = ..., + ) -> None: ... + @override + def __call__(self, *args: Any, **kwargs: Any) -> Any: ... + @override + def then( # pyright: ignore[reportIncompatibleMethodOverride] # ty: ignore[invalid-method-override] + self, + callback: Callable[..., Any], + on_error: Callable[..., Any] | None = ..., + ) -> promise: ... + @override + def throw( + self, + exc: BaseException | None = ..., + tb: TracebackType | None = ..., + propagate: bool = ..., + ) -> None: ... + def throw1(self, exc: BaseException | None = ...) -> None: ... + @override + def cancel(self) -> None: ... + +__all__ = ["promise"] diff --git a/vine-stubs/synchronization.pyi b/vine-stubs/synchronization.pyi index e69de29..904f2c6 100644 --- a/vine-stubs/synchronization.pyi +++ b/vine-stubs/synchronization.pyi @@ -0,0 +1,47 @@ +from collections.abc import Callable +from types import TracebackType +from typing import Any + +from typing_extensions import override +from vine.abstract import Thenable +from vine.promises import promise + +class barrier(Thenable): + p: promise + args: tuple[Any, ...] + kwargs: dict[str, Any] + ready: bool + cancelled: bool + finalized: bool + + def __init__( + self, + promises: list[promise] | None = ..., + args: tuple[Any, ...] | None = ..., + kwargs: dict[str, Any] | None = ..., + callback: Callable[..., Any] | None = ..., + size: int | None = ..., + ) -> None: ... + @override + def __call__(self, *args: Any, **kwargs: Any) -> Any: ... + def add(self, p: promise) -> promise: ... + def add_noincr(self, p: promise) -> promise: ... + @override + def cancel(self) -> None: ... + def finalize(self) -> None: ... + @override + def then( # pyright: ignore[reportIncompatibleMethodOverride] # ty: ignore[invalid-method-override] + self, + callback: Callable[..., Any], + errback: Callable[..., Any] | None = ..., + ) -> promise: ... + @override + def throw( + self, + exc: BaseException | None = ..., + tb: TracebackType | None = ..., + propagate: bool = ..., + ) -> None: ... + def throw1(self, exc: BaseException | None = ...) -> None: ... + +__all__ = ["barrier"] diff --git a/vine-stubs/utils.pyi b/vine-stubs/utils.pyi new file mode 100644 index 0000000..37fba2e --- /dev/null +++ b/vine-stubs/utils.pyi @@ -0,0 +1,26 @@ +from collections.abc import Callable +from functools import partial as partial +from types import TracebackType +from typing import Any, TypeVar + +_F = TypeVar("_F", bound=Callable[..., Any]) + +WRAPPER_ASSIGNMENTS: tuple[str, ...] +WRAPPER_UPDATES: tuple[str, ...] + +def update_wrapper( + wrapper: _F, + wrapped: Callable[..., Any], + assigned: tuple[str, ...] = ..., + updated: tuple[str, ...] = ..., +) -> _F: ... +def wraps( + wrapped: Callable[..., Any], + assigned: tuple[str, ...] = ..., + updated: tuple[str, ...] = ..., +) -> Callable[[_F], _F]: ... +def reraise( + tp: type[BaseException], value: BaseException, tb: TracebackType | None = ... +) -> None: ... + +__all__ = ["update_wrapper", "wraps"]