Skip to content

Commit 723db2f

Browse files
Add concurrent.interpreters stubs for 3.14.0b3 (#14307)
1 parent 217be66 commit 723db2f

File tree

6 files changed

+172
-5
lines changed

6 files changed

+172
-5
lines changed

stdlib/@tests/stubtest_allowlists/py314.txt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
# TODO: New errors in Python 3.14 that need to be fixed or moved below
33
# ====================================================================
44

5-
concurrent.interpreters
65
concurrent.futures.InterpreterPoolExecutor.__init__
76
concurrent.futures.InterpreterPoolExecutor.prepare_context
87
concurrent.futures.interpreter.ExecutionFailed
@@ -38,6 +37,15 @@ types.UnionType.__qualname__
3837
# Assigning `__new__` causes `func` not to get recognized.
3938
functools.partialmethod.__new__
4039

40+
# decorator approximated by classmethod
41+
concurrent.interpreters._crossinterp.classonly.*
42+
43+
# object() sentinels at runtime represented by NewTypes in the stubs
44+
concurrent.interpreters._crossinterp.UNBOUND_ERROR
45+
concurrent.interpreters._crossinterp.UNBOUND_REMOVE
46+
concurrent.interpreters._queues.UNBOUND_ERROR
47+
concurrent.interpreters._queues.UNBOUND_REMOVE
48+
4149
# ====================================
4250
# Pre-existing errors from Python 3.13
4351
# ====================================

stdlib/VERSIONS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ compileall: 3.0-
124124
compression: 3.14-
125125
concurrent: 3.2-
126126
concurrent.futures.interpreter: 3.14-
127+
concurrent.interpreters: 3.14-
127128
configparser: 3.0-
128129
contextlib: 3.0-
129130
contextvars: 3.7-

stdlib/_interpreters.pyi

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import types
22
from collections.abc import Callable
3-
from typing import Any, Final, Literal, SupportsIndex
3+
from typing import Any, Final, Literal, SupportsIndex, TypeVar
44
from typing_extensions import TypeAlias
55

6+
_R = TypeVar("_R")
7+
68
_Configs: TypeAlias = Literal["default", "isolated", "legacy", "empty", ""]
79
_SharedDict: TypeAlias = dict[str, Any] # many objects can be shared
810

@@ -21,7 +23,7 @@ def get_current() -> tuple[int, int]: ...
2123
def get_main() -> tuple[int, int]: ...
2224
def is_running(id: SupportsIndex, *, restrict: bool = False) -> bool: ...
2325
def get_config(id: SupportsIndex, *, restrict: bool = False) -> types.SimpleNamespace: ...
24-
def whence(id: SupportsIndex) -> int: ...
26+
def whence(id: SupportsIndex) -> _Whence: ...
2527
def exec(
2628
id: SupportsIndex,
2729
code: str | types.CodeType | Callable[[], object],
@@ -31,12 +33,12 @@ def exec(
3133
) -> None | types.SimpleNamespace: ...
3234
def call(
3335
id: SupportsIndex,
34-
callable: Callable[..., object],
36+
callable: Callable[..., _R],
3537
args: tuple[object, ...] | None = None,
3638
kwargs: dict[str, object] | None = None,
3739
*,
3840
restrict: bool = False,
39-
) -> object: ...
41+
) -> tuple[_R, types.SimpleNamespace]: ...
4042
def run_string(
4143
id: SupportsIndex,
4244
script: str | types.CodeType | Callable[[], object],
@@ -53,6 +55,7 @@ def decref(id: SupportsIndex, *, restrict: bool = False) -> None: ...
5355
def is_shareable(obj: object) -> bool: ...
5456
def capture_exception(exc: BaseException | None = None) -> types.SimpleNamespace: ...
5557

58+
_Whence: TypeAlias = Literal[0, 1, 2, 3, 4, 5]
5659
WHENCE_UNKNOWN: Final = 0
5760
WHENCE_RUNTIME: Final = 1
5861
WHENCE_LEGACY_CAPI: Final = 2
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import sys
2+
import threading
3+
import types
4+
from collections.abc import Callable
5+
from typing import Any, Literal, TypeVar
6+
from typing_extensions import ParamSpec, Self
7+
8+
if sys.version_info >= (3, 13): # needed to satisfy pyright checks for Python <3.13
9+
from _interpreters import (
10+
InterpreterError as InterpreterError,
11+
InterpreterNotFoundError as InterpreterNotFoundError,
12+
NotShareableError as NotShareableError,
13+
_SharedDict,
14+
_Whence,
15+
is_shareable as is_shareable,
16+
)
17+
18+
from ._queues import Queue as Queue, QueueEmpty as QueueEmpty, QueueFull as QueueFull, create as create_queue
19+
20+
__all__ = [
21+
"ExecutionFailed",
22+
"Interpreter",
23+
"InterpreterError",
24+
"InterpreterNotFoundError",
25+
"NotShareableError",
26+
"Queue",
27+
"QueueEmpty",
28+
"QueueFull",
29+
"create",
30+
"create_queue",
31+
"get_current",
32+
"get_main",
33+
"is_shareable",
34+
"list_all",
35+
]
36+
37+
_R = TypeVar("_R")
38+
_P = ParamSpec("_P")
39+
40+
class ExecutionFailed(InterpreterError):
41+
excinfo: types.SimpleNamespace
42+
43+
def __init__(self, excinfo: types.SimpleNamespace) -> None: ...
44+
45+
def create() -> Interpreter: ...
46+
def list_all() -> list[Interpreter]: ...
47+
def get_current() -> Interpreter: ...
48+
def get_main() -> Interpreter: ...
49+
50+
class Interpreter:
51+
def __new__(cls, id: int, /, _whence: _Whence | None = None, _ownsref: bool | None = None) -> Self: ...
52+
def __reduce__(self) -> tuple[type[Self], int]: ...
53+
def __hash__(self) -> int: ...
54+
def __del__(self) -> None: ...
55+
@property
56+
def id(self) -> int: ...
57+
@property
58+
def whence(
59+
self,
60+
) -> Literal["unknown", "runtime init", "legacy C-API", "C-API", "cross-interpreter C-API", "_interpreters module"]: ...
61+
def is_running(self) -> bool: ...
62+
def close(self) -> None: ...
63+
def prepare_main(
64+
self, ns: _SharedDict | None = None, /, **kwargs: Any
65+
) -> None: ... # kwargs has same value restrictions as _SharedDict
66+
def exec(self, code: str | types.CodeType | Callable[[], object], /) -> None: ...
67+
def call(self, callable: Callable[_P, _R], /, *args: _P.args, **kwargs: _P.kwargs) -> _R: ...
68+
def call_in_thread(self, callable: Callable[_P, object], /, *args: _P.args, **kwargs: _P.kwargs) -> threading.Thread: ...
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import sys
2+
from collections.abc import Callable
3+
from typing import Final, NewType
4+
from typing_extensions import Never, Self, TypeAlias
5+
6+
if sys.version_info >= (3, 13): # needed to satisfy pyright checks for Python <3.13
7+
from _interpqueues import _UnboundOp
8+
9+
class ItemInterpreterDestroyed(Exception): ...
10+
# Actually a descriptor that behaves similarly to classmethod but prevents
11+
# access from instances.
12+
classonly = classmethod
13+
14+
class UnboundItem:
15+
def __new__(cls) -> Never: ...
16+
@classonly
17+
def singleton(cls, kind: str, module: str, name: str = "UNBOUND") -> Self: ...
18+
19+
# Sentinel types and alias that don't exist at runtime.
20+
_UnboundErrorType = NewType("_UnboundErrorType", object)
21+
_UnboundRemoveType = NewType("_UnboundRemoveType", object)
22+
_AnyUnbound: TypeAlias = _UnboundErrorType | _UnboundRemoveType | UnboundItem
23+
24+
UNBOUND_ERROR: Final[_UnboundErrorType]
25+
UNBOUND_REMOVE: Final[_UnboundRemoveType]
26+
UNBOUND: Final[UnboundItem] # analogous to UNBOUND_REPLACE in C
27+
28+
def serialize_unbound(unbound: _AnyUnbound) -> tuple[_UnboundOp]: ...
29+
def resolve_unbound(flag: _UnboundOp, exctype_destroyed: Callable[[str], BaseException]) -> UnboundItem: ...
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import queue
2+
import sys
3+
from typing import Final, SupportsIndex
4+
from typing_extensions import Self
5+
6+
if sys.version_info >= (3, 13): # needed to satisfy pyright checks for Python <3.13
7+
from _interpqueues import QueueError as QueueError, QueueNotFoundError as QueueNotFoundError
8+
9+
from . import _crossinterp
10+
from ._crossinterp import UNBOUND_ERROR as UNBOUND_ERROR, UNBOUND_REMOVE as UNBOUND_REMOVE, UnboundItem, _AnyUnbound
11+
12+
__all__ = [
13+
"UNBOUND",
14+
"UNBOUND_ERROR",
15+
"UNBOUND_REMOVE",
16+
"ItemInterpreterDestroyed",
17+
"Queue",
18+
"QueueEmpty",
19+
"QueueError",
20+
"QueueFull",
21+
"QueueNotFoundError",
22+
"create",
23+
"list_all",
24+
]
25+
26+
class QueueEmpty(QueueError, queue.Empty): ...
27+
class QueueFull(QueueError, queue.Full): ...
28+
class ItemInterpreterDestroyed(QueueError, _crossinterp.ItemInterpreterDestroyed): ...
29+
UNBOUND: Final[UnboundItem]
30+
31+
def create(maxsize: int = 0, *, unbounditems: _AnyUnbound = ...) -> Queue: ...
32+
def list_all() -> list[Queue]: ...
33+
34+
class Queue:
35+
def __new__(cls, id: int, /) -> Self: ...
36+
def __del__(self) -> None: ...
37+
def __hash__(self) -> int: ...
38+
def __reduce__(self) -> tuple[type[Self], int]: ...
39+
@property
40+
def id(self) -> int: ...
41+
@property
42+
def unbounditems(self) -> _AnyUnbound: ...
43+
@property
44+
def maxsize(self) -> int: ...
45+
def empty(self) -> bool: ...
46+
def full(self) -> bool: ...
47+
def qsize(self) -> int: ...
48+
def put(
49+
self,
50+
obj: object,
51+
timeout: SupportsIndex | None = None,
52+
*,
53+
unbounditems: _AnyUnbound | None = None,
54+
_delay: float = ...,
55+
) -> None: ...
56+
def put_nowait(self, obj: object, *, unbounditems: _AnyUnbound | None = None) -> None: ...
57+
def get(self, timeout: SupportsIndex | None = None, *, _delay: float = ...) -> object: ...
58+
def get_nowait(self) -> object: ...

0 commit comments

Comments
 (0)