@@ -59,7 +59,8 @@ not use the positional-only syntax from PEP 570 [#pep570]_, introduced in
59
59
Python 3.8, although type checker authors are encouraged to support it.
60
60
61
61
Stubs are treated as if ``from __future__ import annotations `` is enabled.
62
- In particular, built-in generics and forward references can be used.
62
+ In particular, built-in generics, pipe union syntax (``X | Y ``), and forward
63
+ references can be used.
63
64
64
65
Starting with Python 3.8, the :py:mod: `ast ` module from the standard library supports
65
66
all syntax features required by this PEP. Older Python versions can use the
@@ -170,6 +171,35 @@ specified in ``__all__`` are imported::
170
171
171
172
Type checkers support cyclic imports in stub files.
172
173
174
+ Built-in Generics
175
+ -----------------
176
+
177
+ PEP 585 [#pep585 ]_ built-in generics are generally supported, with
178
+ the following exceptions [#ts-4820 ]_:
179
+
180
+ * Built-in generics don't work in type aliases.
181
+ * Built-in generics don't work in base classes.
182
+ * ``type `` is not supported.
183
+ * Variable length tuples (``tuple[X, ...] ``) are not supported.
184
+
185
+ In these cases, the appropriate types from ``typing `` must be used.
186
+
187
+ Using imports from ``collections.abc `` instead of ``typing `` is
188
+ generally possible and recommended.
189
+
190
+ Unions
191
+ ------
192
+
193
+ Declaring unions with ``Union `` and ``Optional `` is supported by all
194
+ type checkers. With the exception of type aliases [#ts-4819 ]_, the shorthand syntax
195
+ is also supported::
196
+
197
+ def foo(x: int | str) -> int | None: ... # recommended
198
+ def foo(x: Union[int, str]) -> Optional[int]: ... # ok
199
+
200
+ TYPE_ALIAS = Union[int, str] # ok
201
+ TYPE_ALIAS = int | str # does not work with all type checkers
202
+
173
203
Module Level Attributes
174
204
-----------------------
175
205
@@ -231,6 +261,8 @@ The class must match the class in which it is declared. Using other classes,
231
261
including sub or super classes, will not work. In addition, the ``self ``
232
262
annotation cannot contain type variables.
233
263
264
+ .. _supported-functions :
265
+
234
266
Functions and Methods
235
267
---------------------
236
268
@@ -282,9 +314,21 @@ But::
282
314
@classmethod
283
315
def create_it(cls: _T) -> _T: ... # cls has type _T
284
316
317
+ PEP 612 [#pep612 ]_ parameter specification variables (``ParamSpec ``)
318
+ are supported in argument and return types, although
319
+ they need to be marked with ``# type: ignore `` to work with all
320
+ type checkers [#ts-4827 ]_::
321
+
322
+ _P = ParamSpec("_P")
323
+ _T = TypeVar("_T")
324
+
325
+ def foo(cb: Callable[_P, _T]) -> Callable[_P, _T]: ... # type: ignore
326
+
327
+ PEP 647 [#pep647 ]_ type guards are supported.
328
+
285
329
Using a function or method body other than the ellipsis literal is currently
286
330
unspecified. Stub authors may experiment with other bodies, but it is up to
287
- individual type checkers how to interpret them.
331
+ individual type checkers how to interpret them::
288
332
289
333
def foo(): ... # compatible
290
334
def bar(): pass # behavior undefined
@@ -465,11 +509,14 @@ No::
465
509
Unsupported Features
466
510
--------------------
467
511
468
- Currently, positional-only argument syntax (PEP 570 [#pep570 ]_),
469
- unions using the pipe operator (``| ``) (PEP 604 [#pep604 ]_),
470
- ``ParamSpec `` (PEP 612 [#pep612 ]_), and ``TypeAlias `` (PEP 613 [#pep613 ]_)
471
- are not supported by all type
472
- checkers and should not be used in stubs.
512
+ Currently, the following features are not supported by all type checkers
513
+ and should not be used in stubs:
514
+
515
+ * Positional-only argument syntax (PEP 570 [#pep570 ]_). Instead, use
516
+ the syntax described in the section :ref: `supported-functions `.
517
+ [#ts-4972 ]_
518
+ * ``TypeAlias `` (PEP 613 [#pep613 ]_). Instead, use a simple
519
+ assigment to define a type alias. [#ts-4913 ]_
473
520
474
521
Type Stub Content
475
522
=================
@@ -594,9 +641,9 @@ the following class::
594
641
595
642
An appropriate stub definition is::
596
643
597
- from typing import Any, Optional
644
+ from typing import Any
598
645
class Foo:
599
- def __getattr__(self, name: str) -> Optional[ Any] : ...
646
+ def __getattr__(self, name: str) -> Any | None : ...
600
647
601
648
Note that only ``__getattr__ ``, not ``__getattribute__ ``, is guaranteed to be
602
649
supported in stubs.
@@ -741,6 +788,29 @@ No::
741
788
x: int
742
789
class MyError(Exception): ... # leave an empty line between the classes
743
790
791
+ Shorthand Syntax
792
+ ----------------
793
+
794
+ Where possible, use shorthand syntax for unions instead of
795
+ ``Union `` or ``Optional ``. ``None `` should be the last
796
+ element of an union. See the Unions _ section for cases where
797
+ using the shorthand syntax is not possible.
798
+
799
+ Yes::
800
+
801
+ def foo(x: str | int) -> None: ...
802
+ def bar(x: str | None) -> int | None: ...
803
+
804
+ No::
805
+
806
+ def foo(x: Union[str, int]) -> None: ...
807
+ def bar(x: Optional[str]) -> Optional[int]: ...
808
+ def baz(x: None | str) -> None: ...
809
+
810
+ But the following is still necessary::
811
+
812
+ TYPE_ALIAS = Optional[Union[str, int]]
813
+
744
814
Module Level Attributes
745
815
-----------------------
746
816
@@ -801,19 +871,19 @@ does not apply to positional-only arguments, which are marked with a double
801
871
underscore.
802
872
803
873
Use the ellipsis literal ``... `` in place of actual default argument
804
- values. Use an explicit ``Optional `` annotation instead of
874
+ values. Use an explicit ``X | None `` annotation instead of
805
875
a ``None `` default.
806
876
807
877
Yes::
808
878
809
879
def foo(x: int = ...) -> None: ...
810
- def bar(y: Optional[ str] = ...) -> None: ...
880
+ def bar(y: str | None = ...) -> None: ...
811
881
812
882
No::
813
883
814
884
def foo(x: int = 0) -> None: ...
815
885
def bar(y: str = None) -> None: ...
816
- def baz(z: Optional[ str] = None) -> None: ...
886
+ def baz(z: str | None = None) -> None: ...
817
887
818
888
Do not annotate ``self `` and ``cls `` in method definitions, except when
819
889
referencing a type variable.
@@ -861,12 +931,12 @@ with an underscore.
861
931
Yes::
862
932
863
933
_T = TypeVar("_T")
864
- _DictList = dict [str, list [Optional[int] ]]
934
+ _DictList = Dict [str, List [Optional[int]]
865
935
866
936
No::
867
937
868
938
T = TypeVar("T")
869
- DictList = dict [str, list [Optional[int]]]
939
+ DictList = Dict [str, List [Optional[int]]]
870
940
871
941
Language Features
872
942
-----------------
@@ -949,7 +1019,9 @@ Maybe::
949
1019
Avoid union return types, since they require ``isinstance() `` checks.
950
1020
Use ``Any `` or ``X | Any `` if necessary.
951
1021
952
- Use built-in generics instead of the aliases from ``typing ``.
1022
+ Use built-in generics instead of the aliases from ``typing ``,
1023
+ where possible. See the section `Built-in Generics `_ for cases,
1024
+ where it's not possible to use them.
953
1025
954
1026
Yes::
955
1027
@@ -1005,8 +1077,18 @@ PEPs
1005
1077
.. [#pep604 ] PEP 604 -- Allow writing union types as X | Y, Prados and Moss (https://www.python.org/dev/peps/pep-0604)
1006
1078
.. [#pep612 ] PEP 612 -- Parameter Specification Variables, Mendoza (https://www.python.org/dev/peps/pep-0612)
1007
1079
.. [#pep613 ] PEP 613 -- Explicit Type Aliases, Zhu (https://www.python.org/dev/peps/pep-0613)
1080
+ .. [#pep647 ] PEP 647 -- User-Defined Type Guards, Traut (https://www.python.org/dev/peps/pep-0647)
1008
1081
.. [#pep3107 ] PEP 3107 -- Function Annotations, Winter and Lownds (https://www.python.org/dev/peps/pep-3107)
1009
1082
1083
+ Bugs
1084
+ ----
1085
+
1086
+ .. [#ts-4819 ] typeshed issue #4819 -- PEP 604 tracker (https://github.com/python/typeshed/issues/4819)
1087
+ .. [#ts-4820 ] typeshed issue #4820 -- PEP 585 tracker (https://github.com/python/typeshed/issues/4820)
1088
+ .. [#ts-4827 ] typeshed issue #4827 -- PEP 612 tracker (https://github.com/python/typeshed/issues/4827)
1089
+ .. [#ts-4913 ] typeshed issue #4913 -- PEP 613 tracker (https://github.com/python/typeshed/issues/4913)
1090
+ .. [#ts-4972 ] typeshed issue #4972 -- PEP 570 tracker (https://github.com/python/typeshed/issues/4972)
1091
+
1010
1092
Copyright
1011
1093
=========
1012
1094
0 commit comments