Skip to content

Commit 5ff32f3

Browse files
3.14: add annotationlib, update typing and inspect (#13985)
1 parent 8bd5455 commit 5ff32f3

File tree

10 files changed

+488
-477
lines changed

10 files changed

+488
-477
lines changed

stdlib/@tests/stubtest_allowlists/py314.txt

Lines changed: 26 additions & 333 deletions
Large diffs are not rendered by default.

stdlib/VERSIONS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ _weakrefset: 3.0-
7878
_winapi: 3.3-
7979
abc: 3.0-
8080
aifc: 3.0-3.12
81+
annotationlib: 3.14-
8182
antigravity: 3.0-
8283
argparse: 3.0-
8384
array: 3.0-

stdlib/_typeshed/__init__.pyi

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,3 +367,14 @@ else:
367367
from enum import Enum
368368

369369
class StrEnum(str, Enum): ...
370+
371+
# Objects that appear in annotations or in type expressions.
372+
# Similar to PEP 747's TypeForm but a little broader.
373+
AnnotationForm: TypeAlias = Any
374+
375+
if sys.version_info >= (3, 14):
376+
from annotationlib import Format
377+
378+
# These return annotations, which can be arbitrary objects
379+
AnnotateFunc: TypeAlias = Callable[[Format], dict[str, AnnotationForm]]
380+
EvaluateFunc: TypeAlias = Callable[[Format], AnnotationForm]

stdlib/annotationlib.pyi

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import sys
2+
from typing import Literal
3+
4+
if sys.version_info >= (3, 14):
5+
import enum
6+
import types
7+
from _typeshed import AnnotateFunc, AnnotationForm, EvaluateFunc, SupportsItems
8+
from collections.abc import Mapping
9+
from typing import Any, ParamSpec, TypeVar, TypeVarTuple, final, overload
10+
from warnings import deprecated
11+
12+
__all__ = [
13+
"Format",
14+
"ForwardRef",
15+
"call_annotate_function",
16+
"call_evaluate_function",
17+
"get_annotate_from_class_namespace",
18+
"get_annotations",
19+
"annotations_to_string",
20+
"type_repr",
21+
]
22+
23+
class Format(enum.IntEnum):
24+
VALUE = 1
25+
VALUE_WITH_FAKE_GLOBALS = 2
26+
FORWARDREF = 3
27+
STRING = 4
28+
29+
@final
30+
class ForwardRef:
31+
__forward_is_argument__: bool
32+
__forward_is_class__: bool
33+
__forward_module__: str | None
34+
def __init__(
35+
self, arg: str, *, module: str | None = None, owner: object = None, is_argument: bool = True, is_class: bool = False
36+
) -> None: ...
37+
@overload
38+
def evaluate(
39+
self,
40+
*,
41+
globals: dict[str, Any] | None = None,
42+
locals: Mapping[str, Any] | None = None,
43+
type_params: tuple[TypeVar | ParamSpec | TypeVarTuple, ...] | None = None,
44+
owner: object = None,
45+
format: Literal[Format.STRING],
46+
) -> str: ...
47+
@overload
48+
def evaluate(
49+
self,
50+
*,
51+
globals: dict[str, Any] | None = None,
52+
locals: Mapping[str, Any] | None = None,
53+
type_params: tuple[TypeVar | ParamSpec | TypeVarTuple, ...] | None = None,
54+
owner: object = None,
55+
format: Literal[Format.FORWARDREF],
56+
) -> AnnotationForm | ForwardRef: ...
57+
@overload
58+
def evaluate(
59+
self,
60+
*,
61+
globals: dict[str, Any] | None = None,
62+
locals: Mapping[str, Any] | None = None,
63+
type_params: tuple[TypeVar | ParamSpec | TypeVarTuple, ...] | None = None,
64+
owner: object = None,
65+
format: Format = Format.VALUE, # noqa: Y011
66+
) -> AnnotationForm: ...
67+
@deprecated("Use ForwardRef.evaluate() or typing.evaluate_forward_ref() instead.")
68+
def _evaluate(
69+
self,
70+
globalns: dict[str, Any] | None,
71+
localns: Mapping[str, Any] | None,
72+
type_params: tuple[TypeVar | ParamSpec | TypeVarTuple, ...] = ...,
73+
*,
74+
recursive_guard: frozenset[str],
75+
) -> AnnotationForm: ...
76+
@property
77+
def __forward_arg__(self) -> str: ...
78+
@property
79+
def __forward_code__(self) -> types.CodeType: ...
80+
def __eq__(self, other: object) -> bool: ...
81+
def __hash__(self) -> int: ...
82+
def __or__(self, other: Any) -> types.UnionType: ...
83+
def __ror__(self, other: Any) -> types.UnionType: ...
84+
85+
@overload
86+
def call_evaluate_function(evaluate: EvaluateFunc, format: Literal[Format.STRING], *, owner: object = None) -> str: ...
87+
@overload
88+
def call_evaluate_function(
89+
evaluate: EvaluateFunc, format: Literal[Format.FORWARDREF], *, owner: object = None
90+
) -> AnnotationForm | ForwardRef: ...
91+
@overload
92+
def call_evaluate_function(evaluate: EvaluateFunc, format: Format, *, owner: object = None) -> AnnotationForm: ...
93+
@overload
94+
def call_annotate_function(
95+
annotate: AnnotateFunc, format: Literal[Format.STRING], *, owner: object = None
96+
) -> dict[str, str]: ...
97+
@overload
98+
def call_annotate_function(
99+
annotate: AnnotateFunc, format: Literal[Format.FORWARDREF], *, owner: object = None
100+
) -> dict[str, AnnotationForm | ForwardRef]: ...
101+
@overload
102+
def call_annotate_function(annotate: AnnotateFunc, format: Format, *, owner: object = None) -> dict[str, AnnotationForm]: ...
103+
def get_annotate_from_class_namespace(obj: Mapping[str, object]) -> AnnotateFunc | None: ...
104+
@overload
105+
def get_annotations(
106+
obj: Any, # any object with __annotations__ or __annotate__
107+
*,
108+
globals: dict[str, object] | None = None,
109+
locals: Mapping[str, object] | None = None,
110+
eval_str: bool = False,
111+
format: Literal[Format.STRING],
112+
) -> dict[str, str]: ...
113+
@overload
114+
def get_annotations(
115+
obj: Any,
116+
*,
117+
globals: dict[str, object] | None = None,
118+
locals: Mapping[str, object] | None = None,
119+
eval_str: bool = False,
120+
format: Literal[Format.FORWARDREF],
121+
) -> dict[str, AnnotationForm | ForwardRef]: ...
122+
@overload
123+
def get_annotations(
124+
obj: Any,
125+
*,
126+
globals: dict[str, object] | None = None,
127+
locals: Mapping[str, object] | None = None,
128+
eval_str: bool = False,
129+
format: Format = Format.VALUE, # noqa: Y011
130+
) -> dict[str, AnnotationForm]: ...
131+
def type_repr(value: object) -> str: ...
132+
def annotations_to_string(annotations: SupportsItems[str, object]) -> dict[str, str]: ...

stdlib/builtins.pyi

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import sys
55
import types
66
from _collections_abc import dict_items, dict_keys, dict_values
77
from _typeshed import (
8+
AnnotationForm,
89
AnyStr_co,
910
ConvertibleToFloat,
1011
ConvertibleToInt,
@@ -72,6 +73,9 @@ from typing_extensions import ( # noqa: Y023
7273
deprecated,
7374
)
7475

76+
if sys.version_info >= (3, 14):
77+
from _typeshed import AnnotateFunc
78+
7579
_T = TypeVar("_T")
7680
_I = TypeVar("_I", default=int)
7781
_T_co = TypeVar("_T_co", covariant=True)
@@ -215,6 +219,9 @@ class type:
215219
def __ror__(self, value: Any, /) -> types.UnionType: ...
216220
if sys.version_info >= (3, 12):
217221
__type_params__: tuple[TypeVar | ParamSpec | TypeVarTuple, ...]
222+
__annotations__: dict[str, AnnotationForm]
223+
if sys.version_info >= (3, 14):
224+
__annotate__: AnnotateFunc | None
218225

219226
class super:
220227
@overload
@@ -1017,7 +1024,9 @@ class function:
10171024
def __globals__(self) -> dict[str, Any]: ...
10181025
__name__: str
10191026
__qualname__: str
1020-
__annotations__: dict[str, Any]
1027+
__annotations__: dict[str, AnnotationForm]
1028+
if sys.version_info >= (3, 14):
1029+
__annotate__: AnnotateFunc | None
10211030
__kwdefaults__: dict[str, Any]
10221031
if sys.version_info >= (3, 10):
10231032
@property

stdlib/inspect.pyi

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import dis
22
import enum
33
import sys
44
import types
5-
from _typeshed import StrPath
5+
from _typeshed import AnnotationForm, StrPath
66
from collections import OrderedDict
77
from collections.abc import AsyncGenerator, Awaitable, Callable, Coroutine, Generator, Mapping, Sequence, Set as AbstractSet
88
from types import (
@@ -28,6 +28,9 @@ from types import (
2828
from typing import Any, ClassVar, Final, Literal, NamedTuple, Protocol, TypeVar, overload
2929
from typing_extensions import ParamSpec, Self, TypeAlias, TypeGuard, TypeIs
3030

31+
if sys.version_info >= (3, 14):
32+
from annotationlib import Format
33+
3134
if sys.version_info >= (3, 11):
3235
__all__ = [
3336
"ArgInfo",
@@ -139,6 +142,8 @@ if sys.version_info >= (3, 11):
139142
"getasyncgenstate",
140143
"BufferFlags",
141144
]
145+
if sys.version_info >= (3, 14):
146+
__all__ += ["CO_HAS_DOCSTRING", "CO_METHOD", "ispackage"]
142147

143148
_P = ParamSpec("_P")
144149
_T = TypeVar("_T")
@@ -172,6 +177,9 @@ CO_COROUTINE: Final = 128
172177
CO_ITERABLE_COROUTINE: Final = 256
173178
CO_ASYNC_GENERATOR: Final = 512
174179
TPFLAGS_IS_ABSTRACT: Final = 1048576
180+
if sys.version_info >= (3, 14):
181+
CO_HAS_DOCSTRING: Final = 67108864
182+
CO_METHOD: Final = 134217728
175183

176184
modulesbyfile: dict[str, Any]
177185

@@ -199,6 +207,11 @@ def getmodulename(path: StrPath) -> str | None: ...
199207
def ismodule(object: object) -> TypeIs[ModuleType]: ...
200208
def isclass(object: object) -> TypeIs[type[Any]]: ...
201209
def ismethod(object: object) -> TypeIs[MethodType]: ...
210+
211+
if sys.version_info >= (3, 14):
212+
# Not TypeIs because it does not return True for all modules
213+
def ispackage(object: object) -> TypeGuard[ModuleType]: ...
214+
202215
def isfunction(object: object) -> TypeIs[FunctionType]: ...
203216

204217
if sys.version_info >= (3, 12):
@@ -294,7 +307,18 @@ _IntrospectableCallable: TypeAlias = Callable[..., Any]
294307
#
295308
# Introspecting callables with the Signature object
296309
#
297-
if sys.version_info >= (3, 10):
310+
if sys.version_info >= (3, 14):
311+
def signature(
312+
obj: _IntrospectableCallable,
313+
*,
314+
follow_wrapped: bool = True,
315+
globals: Mapping[str, Any] | None = None,
316+
locals: Mapping[str, Any] | None = None,
317+
eval_str: bool = False,
318+
annotation_format: Format = Format.VALUE, # noqa: Y011
319+
) -> Signature: ...
320+
321+
elif sys.version_info >= (3, 10):
298322
def signature(
299323
obj: _IntrospectableCallable,
300324
*,
@@ -323,7 +347,19 @@ class Signature:
323347
def bind_partial(self, *args: Any, **kwargs: Any) -> BoundArguments: ...
324348
def replace(self, *, parameters: Sequence[Parameter] | type[_void] | None = ..., return_annotation: Any = ...) -> Self: ...
325349
__replace__ = replace
326-
if sys.version_info >= (3, 10):
350+
if sys.version_info >= (3, 14):
351+
@classmethod
352+
def from_callable(
353+
cls,
354+
obj: _IntrospectableCallable,
355+
*,
356+
follow_wrapped: bool = True,
357+
globals: Mapping[str, Any] | None = None,
358+
locals: Mapping[str, Any] | None = None,
359+
eval_str: bool = False,
360+
annotation_format: Format = Format.VALUE, # noqa: Y011
361+
) -> Self: ...
362+
elif sys.version_info >= (3, 10):
327363
@classmethod
328364
def from_callable(
329365
cls,
@@ -337,20 +373,24 @@ class Signature:
337373
else:
338374
@classmethod
339375
def from_callable(cls, obj: _IntrospectableCallable, *, follow_wrapped: bool = True) -> Self: ...
340-
if sys.version_info >= (3, 13):
376+
if sys.version_info >= (3, 14):
377+
def format(self, *, max_width: int | None = None, quote_annotation_strings: bool = True) -> str: ...
378+
elif sys.version_info >= (3, 13):
341379
def format(self, *, max_width: int | None = None) -> str: ...
342380

343381
def __eq__(self, other: object) -> bool: ...
344382
def __hash__(self) -> int: ...
345383

346-
if sys.version_info >= (3, 10):
384+
if sys.version_info >= (3, 14):
385+
from annotationlib import get_annotations as get_annotations
386+
elif sys.version_info >= (3, 10):
347387
def get_annotations(
348388
obj: Callable[..., object] | type[object] | ModuleType, # any callable, class, or module
349389
*,
350390
globals: Mapping[str, Any] | None = None, # value types depend on the key
351391
locals: Mapping[str, Any] | None = None, # value types depend on the key
352392
eval_str: bool = False,
353-
) -> dict[str, Any]: ... # values are type expressions
393+
) -> dict[str, AnnotationForm]: ... # values are type expressions
354394

355395
# The name is the same as the enum's name in CPython
356396
class _ParameterKind(enum.IntEnum):
@@ -461,7 +501,13 @@ class ArgInfo(NamedTuple):
461501
locals: dict[str, Any]
462502

463503
def getargvalues(frame: FrameType) -> ArgInfo: ...
464-
def formatannotation(annotation: object, base_module: str | None = None) -> str: ...
504+
505+
if sys.version_info >= (3, 14):
506+
def formatannotation(annotation: object, base_module: str | None = None, *, quote_annotation_strings: bool = True) -> str: ...
507+
508+
else:
509+
def formatannotation(annotation: object, base_module: str | None = None) -> str: ...
510+
465511
def formatannotationrelativeto(object: object) -> Callable[[object], str]: ...
466512

467513
if sys.version_info < (3, 11):

stdlib/types.pyi

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import sys
2-
from _typeshed import MaybeNone, SupportsKeysAndGetItem
2+
from _typeshed import AnnotationForm, MaybeNone, SupportsKeysAndGetItem
33
from _typeshed.importlib import LoaderProtocol
44
from collections.abc import (
55
AsyncGenerator,
@@ -19,6 +19,9 @@ from importlib.machinery import ModuleSpec
1919
from typing import Any, ClassVar, Literal, TypeVar, final, overload
2020
from typing_extensions import ParamSpec, Self, TypeAliasType, TypeVarTuple, deprecated
2121

22+
if sys.version_info >= (3, 14):
23+
from _typeshed import AnnotateFunc
24+
2225
__all__ = [
2326
"FunctionType",
2427
"LambdaType",
@@ -77,7 +80,9 @@ class FunctionType:
7780
def __globals__(self) -> dict[str, Any]: ...
7881
__name__: str
7982
__qualname__: str
80-
__annotations__: dict[str, Any]
83+
__annotations__: dict[str, AnnotationForm]
84+
if sys.version_info >= (3, 14):
85+
__annotate__: AnnotateFunc | None
8186
__kwdefaults__: dict[str, Any] | None
8287
if sys.version_info >= (3, 10):
8388
@property
@@ -352,6 +357,10 @@ class ModuleType:
352357
# Redeclaring `__doc__` here helps some type checkers understand that `__doc__` is available
353358
# as an implicit global in all modules, similar to `__name__`, `__file__`, `__spec__`, etc.
354359
__doc__: str | None
360+
__annotations__: dict[str, AnnotationForm]
361+
if sys.version_info >= (3, 14):
362+
__annotate__: AnnotateFunc | None
363+
355364
def __init__(self, name: str, doc: str | None = ...) -> None: ...
356365
# __getattr__ doesn't exist at runtime,
357366
# but having it here in typeshed makes dynamic imports

0 commit comments

Comments
 (0)