mirror of
https://github.com/python/cpython.git
synced 2025-08-09 11:29:45 +00:00
gh-105286: Improve `typing.py` docstrings (#105287) Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Co-authored-by: Nikita Sobolev <mail@sobolevn.me>
This commit is contained in:
parent
2031238eb6
commit
83fc562ea5
1 changed files with 250 additions and 217 deletions
301
Lib/typing.py
301
Lib/typing.py
|
@ -1,22 +1,22 @@
|
||||||
"""
|
"""
|
||||||
The typing module: Support for gradual typing as defined by PEP 484.
|
The typing module: Support for gradual typing as defined by PEP 484 and subsequent PEPs.
|
||||||
|
|
||||||
At large scale, the structure of the module is following:
|
Any name not present in __all__ is an implementation detail
|
||||||
* Imports and exports, all public names should be explicitly added to __all__.
|
that may be changed without notice. Use at your own risk!
|
||||||
* Internal helper functions: these should never be used in code outside this module.
|
|
||||||
* _SpecialForm and its instances (special forms):
|
Among other things, the module includes the following:
|
||||||
Any, NoReturn, Never, ClassVar, Union, Optional, Concatenate, Unpack
|
* Generic, Protocol, and internal machinery to support generic aliases.
|
||||||
* Classes whose instances can be type arguments in addition to types:
|
All subscripted types like X[int], Union[int, str] are generic aliases.
|
||||||
ForwardRef, TypeVar and ParamSpec
|
* Various "special forms" that have unique meanings in type annotations:
|
||||||
* The core of internal generics API: _GenericAlias and _VariadicGenericAlias, the latter is
|
NoReturn, Never, ClassVar, Self, Concatenate, Unpack, and others.
|
||||||
currently only used by Tuple and Callable. All subscripted types like X[int], Union[int, str],
|
* Classes whose instances can be type arguments to generic classes and functions:
|
||||||
etc., are instances of either of these classes.
|
TypeVar, ParamSpec, TypeVarTuple.
|
||||||
* The public counterpart of the generics API consists of two classes: Generic and Protocol.
|
* Public helper functions: get_type_hints, overload, cast, final, and others.
|
||||||
* Public helper functions: get_type_hints, overload, cast, no_type_check,
|
* Several protocols to support duck-typing:
|
||||||
no_type_check_decorator.
|
SupportsFloat, SupportsIndex, SupportsAbs, and others.
|
||||||
* Generic aliases for collections.abc ABCs and few additional protocols.
|
|
||||||
* Special types: NewType, NamedTuple, TypedDict.
|
* Special types: NewType, NamedTuple, TypedDict.
|
||||||
* Wrapper submodules for re and io related types.
|
* Deprecated wrapper submodules for re and io related types.
|
||||||
|
* Deprecated aliases for builtin types and collections.abc ABCs.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from abc import abstractmethod, ABCMeta
|
from abc import abstractmethod, ABCMeta
|
||||||
|
@ -178,7 +178,7 @@ def _type_check(arg, msg, is_argument=True, module=None, *, allow_special_forms=
|
||||||
As a special case, accept None and return type(None) instead. Also wrap strings
|
As a special case, accept None and return type(None) instead. Also wrap strings
|
||||||
into ForwardRef instances. Consider several corner cases, for example plain
|
into ForwardRef instances. Consider several corner cases, for example plain
|
||||||
special forms like Union are not valid, while Union[int, str] is OK, etc.
|
special forms like Union are not valid, while Union[int, str] is OK, etc.
|
||||||
The msg argument is a human-readable error message, e.g::
|
The msg argument is a human-readable error message, e.g.::
|
||||||
|
|
||||||
"Union[arg, ...]: arg should be a type."
|
"Union[arg, ...]: arg should be a type."
|
||||||
|
|
||||||
|
@ -214,7 +214,7 @@ def _should_unflatten_callable_args(typ, args):
|
||||||
"""Internal helper for munging collections.abc.Callable's __args__.
|
"""Internal helper for munging collections.abc.Callable's __args__.
|
||||||
|
|
||||||
The canonical representation for a Callable's __args__ flattens the
|
The canonical representation for a Callable's __args__ flattens the
|
||||||
argument types, see https://bugs.python.org/issue42195. For example:
|
argument types, see https://bugs.python.org/issue42195. For example::
|
||||||
|
|
||||||
collections.abc.Callable[[int, int], str].__args__ == (int, int, str)
|
collections.abc.Callable[[int, int], str].__args__ == (int, int, str)
|
||||||
collections.abc.Callable[ParamSpec, str].__args__ == (ParamSpec, str)
|
collections.abc.Callable[ParamSpec, str].__args__ == (ParamSpec, str)
|
||||||
|
@ -255,9 +255,11 @@ def _type_repr(obj):
|
||||||
|
|
||||||
def _collect_parameters(args):
|
def _collect_parameters(args):
|
||||||
"""Collect all type variables and parameter specifications in args
|
"""Collect all type variables and parameter specifications in args
|
||||||
in order of first appearance (lexicographic order). For example::
|
in order of first appearance (lexicographic order).
|
||||||
|
|
||||||
_collect_parameters((T, Callable[P, T])) == (T, P)
|
For example::
|
||||||
|
|
||||||
|
assert _collect_parameters((T, Callable[P, T])) == (T, P)
|
||||||
"""
|
"""
|
||||||
parameters = []
|
parameters = []
|
||||||
for t in args:
|
for t in args:
|
||||||
|
@ -283,6 +285,7 @@ def _collect_parameters(args):
|
||||||
|
|
||||||
def _check_generic(cls, parameters, elen):
|
def _check_generic(cls, parameters, elen):
|
||||||
"""Check correct count for parameters of a generic cls (internal helper).
|
"""Check correct count for parameters of a generic cls (internal helper).
|
||||||
|
|
||||||
This gives a nice error message in case of count mismatch.
|
This gives a nice error message in case of count mismatch.
|
||||||
"""
|
"""
|
||||||
if not elen:
|
if not elen:
|
||||||
|
@ -317,8 +320,9 @@ def _deduplicate(params):
|
||||||
|
|
||||||
|
|
||||||
def _remove_dups_flatten(parameters):
|
def _remove_dups_flatten(parameters):
|
||||||
"""An internal helper for Union creation and substitution: flatten Unions
|
"""Internal helper for Union creation and substitution.
|
||||||
among parameters, then remove duplicates.
|
|
||||||
|
Flatten Unions among parameters, then remove duplicates.
|
||||||
"""
|
"""
|
||||||
# Flatten out Union[Union[...], ...].
|
# Flatten out Union[Union[...], ...].
|
||||||
params = []
|
params = []
|
||||||
|
@ -332,7 +336,7 @@ def _remove_dups_flatten(parameters):
|
||||||
|
|
||||||
|
|
||||||
def _flatten_literal_params(parameters):
|
def _flatten_literal_params(parameters):
|
||||||
"""An internal helper for Literal creation: flatten Literals among parameters"""
|
"""Internal helper for Literal creation: flatten Literals among parameters."""
|
||||||
params = []
|
params = []
|
||||||
for p in parameters:
|
for p in parameters:
|
||||||
if isinstance(p, _LiteralGenericAlias):
|
if isinstance(p, _LiteralGenericAlias):
|
||||||
|
@ -377,6 +381,7 @@ def _tp_cache(func=None, /, *, typed=False):
|
||||||
|
|
||||||
def _eval_type(t, globalns, localns, recursive_guard=frozenset()):
|
def _eval_type(t, globalns, localns, recursive_guard=frozenset()):
|
||||||
"""Evaluate all forward references in the given type t.
|
"""Evaluate all forward references in the given type t.
|
||||||
|
|
||||||
For use of globalns and localns see the docstring for get_type_hints().
|
For use of globalns and localns see the docstring for get_type_hints().
|
||||||
recursive_guard is used to prevent infinite recursion with a recursive
|
recursive_guard is used to prevent infinite recursion with a recursive
|
||||||
ForwardRef.
|
ForwardRef.
|
||||||
|
@ -409,7 +414,7 @@ def _eval_type(t, globalns, localns, recursive_guard=frozenset()):
|
||||||
|
|
||||||
|
|
||||||
class _Final:
|
class _Final:
|
||||||
"""Mixin to prohibit subclassing"""
|
"""Mixin to prohibit subclassing."""
|
||||||
|
|
||||||
__slots__ = ('__weakref__',)
|
__slots__ = ('__weakref__',)
|
||||||
|
|
||||||
|
@ -419,6 +424,7 @@ class _Final:
|
||||||
|
|
||||||
class _Immutable:
|
class _Immutable:
|
||||||
"""Mixin to indicate that object should not be copied."""
|
"""Mixin to indicate that object should not be copied."""
|
||||||
|
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
def __copy__(self):
|
def __copy__(self):
|
||||||
|
@ -431,8 +437,10 @@ class _Immutable:
|
||||||
class _NotIterable:
|
class _NotIterable:
|
||||||
"""Mixin to prevent iteration, without being compatible with Iterable.
|
"""Mixin to prevent iteration, without being compatible with Iterable.
|
||||||
|
|
||||||
That is, we could do:
|
That is, we could do::
|
||||||
|
|
||||||
def __iter__(self): raise TypeError()
|
def __iter__(self): raise TypeError()
|
||||||
|
|
||||||
But this would make users of this mixin duck type-compatible with
|
But this would make users of this mixin duck type-compatible with
|
||||||
collections.abc.Iterable - isinstance(foo, Iterable) would be True.
|
collections.abc.Iterable - isinstance(foo, Iterable) would be True.
|
||||||
|
|
||||||
|
@ -519,6 +527,7 @@ class Any(metaclass=_AnyMeta):
|
||||||
static type checkers. At runtime, Any should not be used with instance
|
static type checkers. At runtime, Any should not be used with instance
|
||||||
checks.
|
checks.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __new__(cls, *args, **kwargs):
|
def __new__(cls, *args, **kwargs):
|
||||||
if cls is Any:
|
if cls is Any:
|
||||||
raise TypeError("Any cannot be instantiated")
|
raise TypeError("Any cannot be instantiated")
|
||||||
|
@ -528,6 +537,7 @@ class Any(metaclass=_AnyMeta):
|
||||||
@_SpecialForm
|
@_SpecialForm
|
||||||
def NoReturn(self, parameters):
|
def NoReturn(self, parameters):
|
||||||
"""Special type indicating functions that never return.
|
"""Special type indicating functions that never return.
|
||||||
|
|
||||||
Example::
|
Example::
|
||||||
|
|
||||||
from typing import NoReturn
|
from typing import NoReturn
|
||||||
|
@ -539,7 +549,6 @@ def NoReturn(self, parameters):
|
||||||
has no values. Starting in Python 3.11, the Never type should
|
has no values. Starting in Python 3.11, the Never type should
|
||||||
be used for this concept instead. Type checkers should treat the two
|
be used for this concept instead. Type checkers should treat the two
|
||||||
equivalently.
|
equivalently.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
raise TypeError(f"{self} is not subscriptable")
|
raise TypeError(f"{self} is not subscriptable")
|
||||||
|
|
||||||
|
@ -567,7 +576,6 @@ def Never(self, parameters):
|
||||||
print("It's a str")
|
print("It's a str")
|
||||||
case _:
|
case _:
|
||||||
never_call_me(arg) # ok, arg is of type Never
|
never_call_me(arg) # ok, arg is of type Never
|
||||||
|
|
||||||
"""
|
"""
|
||||||
raise TypeError(f"{self} is not subscriptable")
|
raise TypeError(f"{self} is not subscriptable")
|
||||||
|
|
||||||
|
@ -615,7 +623,6 @@ def LiteralString(self, parameters):
|
||||||
Only string literals and other LiteralStrings are compatible
|
Only string literals and other LiteralStrings are compatible
|
||||||
with LiteralString. This provides a tool to help prevent
|
with LiteralString. This provides a tool to help prevent
|
||||||
security issues such as SQL injection.
|
security issues such as SQL injection.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
raise TypeError(f"{self} is not subscriptable")
|
raise TypeError(f"{self} is not subscriptable")
|
||||||
|
|
||||||
|
@ -645,7 +652,8 @@ def Final(self, parameters):
|
||||||
"""Special typing construct to indicate final names to type checkers.
|
"""Special typing construct to indicate final names to type checkers.
|
||||||
|
|
||||||
A final name cannot be re-assigned or overridden in a subclass.
|
A final name cannot be re-assigned or overridden in a subclass.
|
||||||
For example:
|
|
||||||
|
For example::
|
||||||
|
|
||||||
MAX_SIZE: Final = 9000
|
MAX_SIZE: Final = 9000
|
||||||
MAX_SIZE += 1 # Error reported by type checker
|
MAX_SIZE += 1 # Error reported by type checker
|
||||||
|
@ -665,25 +673,29 @@ def Final(self, parameters):
|
||||||
def Union(self, parameters):
|
def Union(self, parameters):
|
||||||
"""Union type; Union[X, Y] means either X or Y.
|
"""Union type; Union[X, Y] means either X or Y.
|
||||||
|
|
||||||
|
On Python 3.10 and higher, the | operator
|
||||||
|
can also be used to denote unions;
|
||||||
|
X | Y means the same thing to the type checker as Union[X, Y].
|
||||||
|
|
||||||
To define a union, use e.g. Union[int, str]. Details:
|
To define a union, use e.g. Union[int, str]. Details:
|
||||||
- The arguments must be types and there must be at least one.
|
- The arguments must be types and there must be at least one.
|
||||||
- None as an argument is a special case and is replaced by
|
- None as an argument is a special case and is replaced by
|
||||||
type(None).
|
type(None).
|
||||||
- Unions of unions are flattened, e.g.::
|
- Unions of unions are flattened, e.g.::
|
||||||
|
|
||||||
Union[Union[int, str], float] == Union[int, str, float]
|
assert Union[Union[int, str], float] == Union[int, str, float]
|
||||||
|
|
||||||
- Unions of a single argument vanish, e.g.::
|
- Unions of a single argument vanish, e.g.::
|
||||||
|
|
||||||
Union[int] == int # The constructor actually returns int
|
assert Union[int] == int # The constructor actually returns int
|
||||||
|
|
||||||
- Redundant arguments are skipped, e.g.::
|
- Redundant arguments are skipped, e.g.::
|
||||||
|
|
||||||
Union[int, str, int] == Union[int, str]
|
assert Union[int, str, int] == Union[int, str]
|
||||||
|
|
||||||
- When comparing unions, the argument order is ignored, e.g.::
|
- When comparing unions, the argument order is ignored, e.g.::
|
||||||
|
|
||||||
Union[int, str] == Union[str, int]
|
assert Union[int, str] == Union[str, int]
|
||||||
|
|
||||||
- You cannot subclass or instantiate a union.
|
- You cannot subclass or instantiate a union.
|
||||||
- You can use Optional[X] as a shorthand for Union[X, None].
|
- You can use Optional[X] as a shorthand for Union[X, None].
|
||||||
|
@ -706,16 +718,13 @@ def _make_union(left, right):
|
||||||
|
|
||||||
TypeVar.__or__ calls this instead of returning types.UnionType
|
TypeVar.__or__ calls this instead of returning types.UnionType
|
||||||
because we want to allow unions between TypeVars and strings
|
because we want to allow unions between TypeVars and strings
|
||||||
(forward references.)
|
(forward references).
|
||||||
"""
|
"""
|
||||||
return Union[left, right]
|
return Union[left, right]
|
||||||
|
|
||||||
@_SpecialForm
|
@_SpecialForm
|
||||||
def Optional(self, parameters):
|
def Optional(self, parameters):
|
||||||
"""Optional type.
|
"""Optional[X] is equivalent to Union[X, None]."""
|
||||||
|
|
||||||
Optional[X] is equivalent to Union[X, None].
|
|
||||||
"""
|
|
||||||
arg = _type_check(parameters, f"{self} requires a single type.")
|
arg = _type_check(parameters, f"{self} requires a single type.")
|
||||||
return Union[arg, type(None)]
|
return Union[arg, type(None)]
|
||||||
|
|
||||||
|
@ -726,7 +735,7 @@ def Literal(self, *parameters):
|
||||||
|
|
||||||
This form can be used to indicate to type checkers that the corresponding
|
This form can be used to indicate to type checkers that the corresponding
|
||||||
variable or function parameter has a value equivalent to the provided
|
variable or function parameter has a value equivalent to the provided
|
||||||
literal (or one of several literals):
|
literal (or one of several literals)::
|
||||||
|
|
||||||
def validate_simple(data: Any) -> Literal[True]: # always returns True
|
def validate_simple(data: Any) -> Literal[True]: # always returns True
|
||||||
...
|
...
|
||||||
|
@ -756,11 +765,11 @@ def Literal(self, *parameters):
|
||||||
|
|
||||||
@_SpecialForm
|
@_SpecialForm
|
||||||
def TypeAlias(self, parameters):
|
def TypeAlias(self, parameters):
|
||||||
"""Special marker indicating that an assignment should
|
"""Special form for marking type aliases.
|
||||||
be recognized as a proper type alias definition by type
|
|
||||||
checkers.
|
|
||||||
|
|
||||||
For example::
|
Use TypeAlias to indicate that an assignment should
|
||||||
|
be recognized as a proper type alias definition by type
|
||||||
|
checkers. For example::
|
||||||
|
|
||||||
Predicate: TypeAlias = Callable[..., bool]
|
Predicate: TypeAlias = Callable[..., bool]
|
||||||
|
|
||||||
|
@ -771,9 +780,11 @@ def TypeAlias(self, parameters):
|
||||||
|
|
||||||
@_SpecialForm
|
@_SpecialForm
|
||||||
def Concatenate(self, parameters):
|
def Concatenate(self, parameters):
|
||||||
"""Used in conjunction with ``ParamSpec`` and ``Callable`` to represent a
|
"""Special form for annotating higher-order functions.
|
||||||
higher order function which adds, removes or transforms parameters of a
|
|
||||||
callable.
|
``Concatenate`` can be sed in conjunction with ``ParamSpec`` and
|
||||||
|
``Callable`` to represent a higher order function which adds, removes or
|
||||||
|
transforms the parameters of a callable.
|
||||||
|
|
||||||
For example::
|
For example::
|
||||||
|
|
||||||
|
@ -795,7 +806,9 @@ def Concatenate(self, parameters):
|
||||||
|
|
||||||
@_SpecialForm
|
@_SpecialForm
|
||||||
def TypeGuard(self, parameters):
|
def TypeGuard(self, parameters):
|
||||||
"""Special typing form used to annotate the return type of a user-defined
|
"""Special typing construct for marking user-defined type guard functions.
|
||||||
|
|
||||||
|
``TypeGuard`` can be used to annotate the return type of a user-defined
|
||||||
type guard function. ``TypeGuard`` only accepts a single type argument.
|
type guard function. ``TypeGuard`` only accepts a single type argument.
|
||||||
At runtime, functions marked this way should return a boolean.
|
At runtime, functions marked this way should return a boolean.
|
||||||
|
|
||||||
|
@ -1102,14 +1115,15 @@ def _is_dunder(attr):
|
||||||
return attr.startswith('__') and attr.endswith('__')
|
return attr.startswith('__') and attr.endswith('__')
|
||||||
|
|
||||||
class _BaseGenericAlias(_Final, _root=True):
|
class _BaseGenericAlias(_Final, _root=True):
|
||||||
"""The central part of internal API.
|
"""The central part of the internal API.
|
||||||
|
|
||||||
This represents a generic version of type 'origin' with type arguments 'params'.
|
This represents a generic version of type 'origin' with type arguments 'params'.
|
||||||
There are two kind of these aliases: user defined and special. The special ones
|
There are two kind of these aliases: user defined and special. The special ones
|
||||||
are wrappers around builtin collections and ABCs in collections.abc. These must
|
are wrappers around builtin collections and ABCs in collections.abc. These must
|
||||||
have 'name' always set. If 'inst' is False, then the alias can't be instantiated,
|
have 'name' always set. If 'inst' is False, then the alias can't be instantiated;
|
||||||
this is used by e.g. typing.List and typing.Dict.
|
this is used by e.g. typing.List and typing.Dict.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, origin, *, inst=True, name=None):
|
def __init__(self, origin, *, inst=True, name=None):
|
||||||
self._inst = inst
|
self._inst = inst
|
||||||
self._name = name
|
self._name = name
|
||||||
|
@ -1188,8 +1202,7 @@ class _GenericAlias(_BaseGenericAlias, _root=True):
|
||||||
# * Note that native container types, e.g. `tuple`, `list`, use
|
# * Note that native container types, e.g. `tuple`, `list`, use
|
||||||
# `types.GenericAlias` instead.
|
# `types.GenericAlias` instead.
|
||||||
# * Parameterized classes:
|
# * Parameterized classes:
|
||||||
# T = TypeVar('T')
|
# class C[T]: pass
|
||||||
# class C(Generic[T]): pass
|
|
||||||
# # C[int] is a _GenericAlias
|
# # C[int] is a _GenericAlias
|
||||||
# * `Callable` aliases, generic `Callable` aliases, and
|
# * `Callable` aliases, generic `Callable` aliases, and
|
||||||
# parameterized `Callable` aliases:
|
# parameterized `Callable` aliases:
|
||||||
|
@ -1562,7 +1575,6 @@ def _value_and_type_iter(parameters):
|
||||||
|
|
||||||
|
|
||||||
class _LiteralGenericAlias(_GenericAlias, _root=True):
|
class _LiteralGenericAlias(_GenericAlias, _root=True):
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
if not isinstance(other, _LiteralGenericAlias):
|
if not isinstance(other, _LiteralGenericAlias):
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
|
@ -1588,7 +1600,7 @@ def Unpack(self, parameters):
|
||||||
|
|
||||||
The type unpack operator takes the child types from some container type,
|
The type unpack operator takes the child types from some container type,
|
||||||
such as `tuple[int, str]` or a `TypeVarTuple`, and 'pulls them out'. For
|
such as `tuple[int, str]` or a `TypeVarTuple`, and 'pulls them out'. For
|
||||||
example:
|
example::
|
||||||
|
|
||||||
# For some generic class `Foo`:
|
# For some generic class `Foo`:
|
||||||
Foo[Unpack[tuple[int, str]]] # Equivalent to Foo[int, str]
|
Foo[Unpack[tuple[int, str]]] # Equivalent to Foo[int, str]
|
||||||
|
@ -1602,13 +1614,18 @@ def Unpack(self, parameters):
|
||||||
Bar[int] # Valid
|
Bar[int] # Valid
|
||||||
Bar[int, str] # Also valid
|
Bar[int, str] # Also valid
|
||||||
|
|
||||||
From Python 3.11, this can also be done using the `*` operator:
|
From Python 3.11, this can also be done using the `*` operator::
|
||||||
|
|
||||||
Foo[*tuple[int, str]]
|
Foo[*tuple[int, str]]
|
||||||
class Bar(Generic[*Ts]): ...
|
class Bar(Generic[*Ts]): ...
|
||||||
|
|
||||||
|
And from Python 3.12, it can be done using built-in syntax for generics::
|
||||||
|
|
||||||
|
Foo[*tuple[int, str]]
|
||||||
|
class Bar[*Ts]: ...
|
||||||
|
|
||||||
The operator can also be used along with a `TypedDict` to annotate
|
The operator can also be used along with a `TypedDict` to annotate
|
||||||
`**kwargs` in a function signature. For instance:
|
`**kwargs` in a function signature. For instance::
|
||||||
|
|
||||||
class Movie(TypedDict):
|
class Movie(TypedDict):
|
||||||
name: str
|
name: str
|
||||||
|
@ -1628,7 +1645,6 @@ def Unpack(self, parameters):
|
||||||
|
|
||||||
|
|
||||||
class _UnpackGenericAlias(_GenericAlias, _root=True):
|
class _UnpackGenericAlias(_GenericAlias, _root=True):
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
# `Unpack` only takes one argument, so __args__ should contain only
|
# `Unpack` only takes one argument, so __args__ should contain only
|
||||||
# a single item.
|
# a single item.
|
||||||
|
@ -1886,10 +1902,11 @@ class Protocol(Generic, metaclass=_ProtocolMeta):
|
||||||
only the presence of given attributes, ignoring their type signatures.
|
only the presence of given attributes, ignoring their type signatures.
|
||||||
Protocol classes can be generic, they are defined as::
|
Protocol classes can be generic, they are defined as::
|
||||||
|
|
||||||
class GenProto(Protocol[T]):
|
class GenProto[T](Protocol):
|
||||||
def meth(self) -> T:
|
def meth(self) -> T:
|
||||||
...
|
...
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
_is_protocol = True
|
_is_protocol = True
|
||||||
_is_runtime_protocol = False
|
_is_runtime_protocol = False
|
||||||
|
@ -1940,12 +1957,13 @@ class _AnnotatedAlias(_NotIterable, _GenericAlias, _root=True):
|
||||||
"""Runtime representation of an annotated type.
|
"""Runtime representation of an annotated type.
|
||||||
|
|
||||||
At its core 'Annotated[t, dec1, dec2, ...]' is an alias for the type 't'
|
At its core 'Annotated[t, dec1, dec2, ...]' is an alias for the type 't'
|
||||||
with extra annotations. The alias behaves like a normal typing alias,
|
with extra annotations. The alias behaves like a normal typing alias.
|
||||||
instantiating is the same as instantiating the underlying type, binding
|
Instantiating is the same as instantiating the underlying type; binding
|
||||||
it to types is also the same.
|
it to types is also the same.
|
||||||
|
|
||||||
The metadata itself is stored in a '__metadata__' attribute as a tuple.
|
The metadata itself is stored in a '__metadata__' attribute as a tuple.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, origin, metadata):
|
def __init__(self, origin, metadata):
|
||||||
if isinstance(origin, _AnnotatedAlias):
|
if isinstance(origin, _AnnotatedAlias):
|
||||||
metadata = origin.__metadata__ + metadata
|
metadata = origin.__metadata__ + metadata
|
||||||
|
@ -1988,7 +2006,7 @@ class _AnnotatedAlias(_NotIterable, _GenericAlias, _root=True):
|
||||||
|
|
||||||
|
|
||||||
class Annotated:
|
class Annotated:
|
||||||
"""Add context specific metadata to a type.
|
"""Add context-specific metadata to a type.
|
||||||
|
|
||||||
Example: Annotated[int, runtime_check.Unsigned] indicates to the
|
Example: Annotated[int, runtime_check.Unsigned] indicates to the
|
||||||
hypothetical runtime_check module that this type is an unsigned int.
|
hypothetical runtime_check module that this type is an unsigned int.
|
||||||
|
@ -2002,24 +2020,24 @@ class Annotated:
|
||||||
- It's an error to call `Annotated` with less than two arguments.
|
- It's an error to call `Annotated` with less than two arguments.
|
||||||
- Access the metadata via the ``__metadata__`` attribute::
|
- Access the metadata via the ``__metadata__`` attribute::
|
||||||
|
|
||||||
Annotated[int, '$'].__metadata__ == ('$',)
|
assert Annotated[int, '$'].__metadata__ == ('$',)
|
||||||
|
|
||||||
- Nested Annotated are flattened::
|
- Nested Annotated are flattened::
|
||||||
|
|
||||||
Annotated[Annotated[T, Ann1, Ann2], Ann3] == Annotated[T, Ann1, Ann2, Ann3]
|
assert Annotated[Annotated[T, Ann1, Ann2], Ann3] == Annotated[T, Ann1, Ann2, Ann3]
|
||||||
|
|
||||||
- Instantiating an annotated type is equivalent to instantiating the
|
- Instantiating an annotated type is equivalent to instantiating the
|
||||||
underlying type::
|
underlying type::
|
||||||
|
|
||||||
Annotated[C, Ann1](5) == C(5)
|
assert Annotated[C, Ann1](5) == C(5)
|
||||||
|
|
||||||
- Annotated can be used as a generic type alias::
|
- Annotated can be used as a generic type alias::
|
||||||
|
|
||||||
Optimized = Annotated[T, runtime.Optimize()]
|
Optimized = Annotated[T, runtime.Optimize()]
|
||||||
Optimized[int] == Annotated[int, runtime.Optimize()]
|
assert Optimized[int] == Annotated[int, runtime.Optimize()]
|
||||||
|
|
||||||
OptimizedList = Annotated[List[T], runtime.Optimize()]
|
OptimizedList = Annotated[List[T], runtime.Optimize()]
|
||||||
OptimizedList[int] == Annotated[List[int], runtime.Optimize()]
|
assert OptimizedList[int] == Annotated[List[int], runtime.Optimize()]
|
||||||
|
|
||||||
- Annotated cannot be used with an unpacked TypeVarTuple::
|
- Annotated cannot be used with an unpacked TypeVarTuple::
|
||||||
|
|
||||||
|
@ -2065,6 +2083,7 @@ def runtime_checkable(cls):
|
||||||
Raise TypeError if applied to a non-protocol class.
|
Raise TypeError if applied to a non-protocol class.
|
||||||
This allows a simple-minded structural check very similar to
|
This allows a simple-minded structural check very similar to
|
||||||
one trick ponies in collections.abc such as Iterable.
|
one trick ponies in collections.abc such as Iterable.
|
||||||
|
|
||||||
For example::
|
For example::
|
||||||
|
|
||||||
@runtime_checkable
|
@runtime_checkable
|
||||||
|
@ -2106,7 +2125,6 @@ def assert_type(val, typ, /):
|
||||||
def greet(name: str) -> None:
|
def greet(name: str) -> None:
|
||||||
assert_type(name, str) # ok
|
assert_type(name, str) # ok
|
||||||
assert_type(name, int) # type checker error
|
assert_type(name, int) # type checker error
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return val
|
return val
|
||||||
|
|
||||||
|
@ -2147,7 +2165,6 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False):
|
||||||
- If two dict arguments are passed, they specify globals and
|
- If two dict arguments are passed, they specify globals and
|
||||||
locals, respectively.
|
locals, respectively.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if getattr(obj, '__no_type_check__', None):
|
if getattr(obj, '__no_type_check__', None):
|
||||||
return {}
|
return {}
|
||||||
# Classes require a special treatment.
|
# Classes require a special treatment.
|
||||||
|
@ -2217,8 +2234,7 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False):
|
||||||
|
|
||||||
|
|
||||||
def _strip_annotations(t):
|
def _strip_annotations(t):
|
||||||
"""Strips the annotations from a given type.
|
"""Strip the annotations from a given type."""
|
||||||
"""
|
|
||||||
if isinstance(t, _AnnotatedAlias):
|
if isinstance(t, _AnnotatedAlias):
|
||||||
return _strip_annotations(t.__origin__)
|
return _strip_annotations(t.__origin__)
|
||||||
if hasattr(t, "__origin__") and t.__origin__ in (Required, NotRequired):
|
if hasattr(t, "__origin__") and t.__origin__ in (Required, NotRequired):
|
||||||
|
@ -2246,16 +2262,16 @@ def get_origin(tp):
|
||||||
"""Get the unsubscripted version of a type.
|
"""Get the unsubscripted version of a type.
|
||||||
|
|
||||||
This supports generic types, Callable, Tuple, Union, Literal, Final, ClassVar
|
This supports generic types, Callable, Tuple, Union, Literal, Final, ClassVar
|
||||||
and Annotated. Return None for unsupported types. Examples::
|
Annotated, and others. Return None for unsupported types. Examples::
|
||||||
|
|
||||||
get_origin(Literal[42]) is Literal
|
assert get_origin(Literal[42]) is Literal
|
||||||
get_origin(int) is None
|
assert get_origin(int) is None
|
||||||
get_origin(ClassVar[int]) is ClassVar
|
assert get_origin(ClassVar[int]) is ClassVar
|
||||||
get_origin(Generic) is Generic
|
assert get_origin(Generic) is Generic
|
||||||
get_origin(Generic[T]) is Generic
|
assert get_origin(Generic[T]) is Generic
|
||||||
get_origin(Union[T, int]) is Union
|
assert get_origin(Union[T, int]) is Union
|
||||||
get_origin(List[Tuple[T, T]][int]) == list
|
assert get_origin(List[Tuple[T, T]][int]) is list
|
||||||
get_origin(P.args) is P
|
assert get_origin(P.args) is P
|
||||||
"""
|
"""
|
||||||
if isinstance(tp, _AnnotatedAlias):
|
if isinstance(tp, _AnnotatedAlias):
|
||||||
return Annotated
|
return Annotated
|
||||||
|
@ -2273,12 +2289,14 @@ def get_args(tp):
|
||||||
"""Get type arguments with all substitutions performed.
|
"""Get type arguments with all substitutions performed.
|
||||||
|
|
||||||
For unions, basic simplifications used by Union constructor are performed.
|
For unions, basic simplifications used by Union constructor are performed.
|
||||||
|
|
||||||
Examples::
|
Examples::
|
||||||
get_args(Dict[str, int]) == (str, int)
|
|
||||||
get_args(int) == ()
|
assert get_args(Dict[str, int]) == (str, int)
|
||||||
get_args(Union[int, Union[T, int], str][int]) == (int, str)
|
assert get_args(int) == ()
|
||||||
get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int])
|
assert get_args(Union[int, Union[T, int], str][int]) == (int, str)
|
||||||
get_args(Callable[[], T][int]) == ([], int)
|
assert get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int])
|
||||||
|
assert get_args(Callable[[], T][int]) == ([], int)
|
||||||
"""
|
"""
|
||||||
if isinstance(tp, _AnnotatedAlias):
|
if isinstance(tp, _AnnotatedAlias):
|
||||||
return (tp.__origin__,) + tp.__metadata__
|
return (tp.__origin__,) + tp.__metadata__
|
||||||
|
@ -2293,9 +2311,10 @@ def get_args(tp):
|
||||||
|
|
||||||
|
|
||||||
def is_typeddict(tp):
|
def is_typeddict(tp):
|
||||||
"""Check if an annotation is a TypedDict class
|
"""Check if an annotation is a TypedDict class.
|
||||||
|
|
||||||
For example::
|
For example::
|
||||||
|
|
||||||
class Film(TypedDict):
|
class Film(TypedDict):
|
||||||
title: str
|
title: str
|
||||||
year: int
|
year: int
|
||||||
|
@ -2327,7 +2346,6 @@ def assert_never(arg: Never, /) -> Never:
|
||||||
reachable, it will emit an error.
|
reachable, it will emit an error.
|
||||||
|
|
||||||
At runtime, this throws an exception when called.
|
At runtime, this throws an exception when called.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
value = repr(arg)
|
value = repr(arg)
|
||||||
if len(value) > _ASSERT_NEVER_REPR_MAX_LENGTH:
|
if len(value) > _ASSERT_NEVER_REPR_MAX_LENGTH:
|
||||||
|
@ -2377,7 +2395,6 @@ def no_type_check_decorator(decorator):
|
||||||
This wraps the decorator with something that wraps the decorated
|
This wraps the decorator with something that wraps the decorated
|
||||||
function in @no_type_check.
|
function in @no_type_check.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@functools.wraps(decorator)
|
@functools.wraps(decorator)
|
||||||
def wrapped_decorator(*args, **kwds):
|
def wrapped_decorator(*args, **kwds):
|
||||||
func = decorator(*args, **kwds)
|
func = decorator(*args, **kwds)
|
||||||
|
@ -2404,7 +2421,7 @@ def overload(func):
|
||||||
"""Decorator for overloaded functions/methods.
|
"""Decorator for overloaded functions/methods.
|
||||||
|
|
||||||
In a stub file, place two or more stub definitions for the same
|
In a stub file, place two or more stub definitions for the same
|
||||||
function in a row, each decorated with @overload. For example:
|
function in a row, each decorated with @overload. For example::
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def utf8(value: None) -> None: ...
|
def utf8(value: None) -> None: ...
|
||||||
|
@ -2415,7 +2432,7 @@ def overload(func):
|
||||||
|
|
||||||
In a non-stub file (i.e. a regular .py file), do the same but
|
In a non-stub file (i.e. a regular .py file), do the same but
|
||||||
follow it with an implementation. The implementation should *not*
|
follow it with an implementation. The implementation should *not*
|
||||||
be decorated with @overload. For example:
|
be decorated with @overload. For example::
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def utf8(value: None) -> None: ...
|
def utf8(value: None) -> None: ...
|
||||||
|
@ -2424,7 +2441,7 @@ def overload(func):
|
||||||
@overload
|
@overload
|
||||||
def utf8(value: str) -> bytes: ...
|
def utf8(value: str) -> bytes: ...
|
||||||
def utf8(value):
|
def utf8(value):
|
||||||
# implementation goes here
|
... # implementation goes here
|
||||||
|
|
||||||
The overloads for a function can be retrieved at runtime using the
|
The overloads for a function can be retrieved at runtime using the
|
||||||
get_overloads() function.
|
get_overloads() function.
|
||||||
|
@ -2457,11 +2474,12 @@ def clear_overloads():
|
||||||
|
|
||||||
|
|
||||||
def final(f):
|
def final(f):
|
||||||
"""A decorator to indicate final methods and final classes.
|
"""Decorator to indicate final methods and final classes.
|
||||||
|
|
||||||
Use this decorator to indicate to type checkers that the decorated
|
Use this decorator to indicate to type checkers that the decorated
|
||||||
method cannot be overridden, and decorated class cannot be subclassed.
|
method cannot be overridden, and decorated class cannot be subclassed.
|
||||||
For example:
|
|
||||||
|
For example::
|
||||||
|
|
||||||
class Base:
|
class Base:
|
||||||
@final
|
@final
|
||||||
|
@ -2478,8 +2496,8 @@ def final(f):
|
||||||
...
|
...
|
||||||
|
|
||||||
There is no runtime checking of these properties. The decorator
|
There is no runtime checking of these properties. The decorator
|
||||||
sets the ``__final__`` attribute to ``True`` on the decorated object
|
attempts to set the ``__final__`` attribute to ``True`` on the decorated
|
||||||
to allow runtime introspection.
|
object to allow runtime introspection.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
f.__final__ = True
|
f.__final__ = True
|
||||||
|
@ -2526,13 +2544,15 @@ Container = _alias(collections.abc.Container, 1)
|
||||||
Collection = _alias(collections.abc.Collection, 1)
|
Collection = _alias(collections.abc.Collection, 1)
|
||||||
Callable = _CallableType(collections.abc.Callable, 2)
|
Callable = _CallableType(collections.abc.Callable, 2)
|
||||||
Callable.__doc__ = \
|
Callable.__doc__ = \
|
||||||
"""Callable type; Callable[[int], str] is a function of (int) -> str.
|
"""Deprecated alias to collections.abc.Callable.
|
||||||
|
|
||||||
|
Callable[[int], str] signifies a function of (int) -> str.
|
||||||
The subscription syntax must always be used with exactly two
|
The subscription syntax must always be used with exactly two
|
||||||
values: the argument list and the return type. The argument list
|
values: the argument list and the return type.
|
||||||
must be a list of types or ellipsis; the return type must be a single type.
|
The argument list must be a list of types, a ParamSpec or ellipsis.
|
||||||
|
The return type must be a single type.
|
||||||
|
|
||||||
There is no syntax to indicate optional or keyword arguments,
|
There is no syntax to indicate optional or keyword arguments;
|
||||||
such function types are rarely used as callback types.
|
such function types are rarely used as callback types.
|
||||||
"""
|
"""
|
||||||
AbstractSet = _alias(collections.abc.Set, 1, name='AbstractSet')
|
AbstractSet = _alias(collections.abc.Set, 1, name='AbstractSet')
|
||||||
|
@ -2548,7 +2568,9 @@ ByteString = _DeprecatedGenericAlias(
|
||||||
# Tuple accepts variable number of parameters.
|
# Tuple accepts variable number of parameters.
|
||||||
Tuple = _TupleType(tuple, -1, inst=False, name='Tuple')
|
Tuple = _TupleType(tuple, -1, inst=False, name='Tuple')
|
||||||
Tuple.__doc__ = \
|
Tuple.__doc__ = \
|
||||||
"""Tuple type; Tuple[X, Y] is the cross-product type of X and Y.
|
"""Deprecated alias to builtins.tuple.
|
||||||
|
|
||||||
|
Tuple[X, Y] is the cross-product type of X and Y.
|
||||||
|
|
||||||
Example: Tuple[T1, T2] is a tuple of two elements corresponding
|
Example: Tuple[T1, T2] is a tuple of two elements corresponding
|
||||||
to type variables T1 and T2. Tuple[int, float, str] is a tuple
|
to type variables T1 and T2. Tuple[int, float, str] is a tuple
|
||||||
|
@ -2575,8 +2597,9 @@ Generator = _alias(collections.abc.Generator, 3)
|
||||||
AsyncGenerator = _alias(collections.abc.AsyncGenerator, 2)
|
AsyncGenerator = _alias(collections.abc.AsyncGenerator, 2)
|
||||||
Type = _alias(type, 1, inst=False, name='Type')
|
Type = _alias(type, 1, inst=False, name='Type')
|
||||||
Type.__doc__ = \
|
Type.__doc__ = \
|
||||||
"""A special construct usable to annotate class objects.
|
"""Deprecated alias to builtins.type.
|
||||||
|
|
||||||
|
builtins.type or typing.Type can be used to annotate class objects.
|
||||||
For example, suppose we have the following classes::
|
For example, suppose we have the following classes::
|
||||||
|
|
||||||
class User: ... # Abstract base for User classes
|
class User: ... # Abstract base for User classes
|
||||||
|
@ -2587,8 +2610,7 @@ Type.__doc__ = \
|
||||||
And a function that takes a class argument that's a subclass of
|
And a function that takes a class argument that's a subclass of
|
||||||
User and returns an instance of the corresponding class::
|
User and returns an instance of the corresponding class::
|
||||||
|
|
||||||
U = TypeVar('U', bound=User)
|
def new_user[U](user_class: Type[U]) -> U:
|
||||||
def new_user(user_class: Type[U]) -> U:
|
|
||||||
user = user_class()
|
user = user_class()
|
||||||
# (Here we could write the user object to a database)
|
# (Here we could write the user object to a database)
|
||||||
return user
|
return user
|
||||||
|
@ -2602,6 +2624,7 @@ Type.__doc__ = \
|
||||||
@runtime_checkable
|
@runtime_checkable
|
||||||
class SupportsInt(Protocol):
|
class SupportsInt(Protocol):
|
||||||
"""An ABC with one abstract method __int__."""
|
"""An ABC with one abstract method __int__."""
|
||||||
|
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
@ -2612,6 +2635,7 @@ class SupportsInt(Protocol):
|
||||||
@runtime_checkable
|
@runtime_checkable
|
||||||
class SupportsFloat(Protocol):
|
class SupportsFloat(Protocol):
|
||||||
"""An ABC with one abstract method __float__."""
|
"""An ABC with one abstract method __float__."""
|
||||||
|
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
@ -2622,6 +2646,7 @@ class SupportsFloat(Protocol):
|
||||||
@runtime_checkable
|
@runtime_checkable
|
||||||
class SupportsComplex(Protocol):
|
class SupportsComplex(Protocol):
|
||||||
"""An ABC with one abstract method __complex__."""
|
"""An ABC with one abstract method __complex__."""
|
||||||
|
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
@ -2632,6 +2657,7 @@ class SupportsComplex(Protocol):
|
||||||
@runtime_checkable
|
@runtime_checkable
|
||||||
class SupportsBytes(Protocol):
|
class SupportsBytes(Protocol):
|
||||||
"""An ABC with one abstract method __bytes__."""
|
"""An ABC with one abstract method __bytes__."""
|
||||||
|
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
@ -2642,6 +2668,7 @@ class SupportsBytes(Protocol):
|
||||||
@runtime_checkable
|
@runtime_checkable
|
||||||
class SupportsIndex(Protocol):
|
class SupportsIndex(Protocol):
|
||||||
"""An ABC with one abstract method __index__."""
|
"""An ABC with one abstract method __index__."""
|
||||||
|
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
@ -2652,6 +2679,7 @@ class SupportsIndex(Protocol):
|
||||||
@runtime_checkable
|
@runtime_checkable
|
||||||
class SupportsAbs[T](Protocol):
|
class SupportsAbs[T](Protocol):
|
||||||
"""An ABC with one abstract method __abs__ that is covariant in its return type."""
|
"""An ABC with one abstract method __abs__ that is covariant in its return type."""
|
||||||
|
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
@ -2662,6 +2690,7 @@ class SupportsAbs[T](Protocol):
|
||||||
@runtime_checkable
|
@runtime_checkable
|
||||||
class SupportsRound[T](Protocol):
|
class SupportsRound[T](Protocol):
|
||||||
"""An ABC with one abstract method __round__ that is covariant in its return type."""
|
"""An ABC with one abstract method __round__ that is covariant in its return type."""
|
||||||
|
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
@ -2688,7 +2717,6 @@ _special = frozenset({'__module__', '__name__', '__annotations__'})
|
||||||
|
|
||||||
|
|
||||||
class NamedTupleMeta(type):
|
class NamedTupleMeta(type):
|
||||||
|
|
||||||
def __new__(cls, typename, bases, ns):
|
def __new__(cls, typename, bases, ns):
|
||||||
assert _NamedTuple in bases
|
assert _NamedTuple in bases
|
||||||
for base in bases:
|
for base in bases:
|
||||||
|
@ -2740,10 +2768,9 @@ def NamedTuple(typename, fields=None, /, **kwargs):
|
||||||
The resulting class has an extra __annotations__ attribute, giving a
|
The resulting class has an extra __annotations__ attribute, giving a
|
||||||
dict that maps field names to types. (The field names are also in
|
dict that maps field names to types. (The field names are also in
|
||||||
the _fields attribute, which is part of the namedtuple API.)
|
the _fields attribute, which is part of the namedtuple API.)
|
||||||
Alternative equivalent keyword syntax is also accepted::
|
An alternative equivalent functional syntax is also accepted::
|
||||||
|
|
||||||
Employee = NamedTuple('Employee', name=str, id=int)
|
|
||||||
|
|
||||||
|
Employee = NamedTuple('Employee', [('name', str), ('id', int)])
|
||||||
"""
|
"""
|
||||||
if fields is None:
|
if fields is None:
|
||||||
fields = kwargs.items()
|
fields = kwargs.items()
|
||||||
|
@ -2765,7 +2792,7 @@ NamedTuple.__mro_entries__ = _namedtuple_mro_entries
|
||||||
|
|
||||||
class _TypedDictMeta(type):
|
class _TypedDictMeta(type):
|
||||||
def __new__(cls, name, bases, ns, total=True):
|
def __new__(cls, name, bases, ns, total=True):
|
||||||
"""Create new typed dict class object.
|
"""Create a new typed dict class object.
|
||||||
|
|
||||||
This method is called when TypedDict is subclassed,
|
This method is called when TypedDict is subclassed,
|
||||||
or when TypedDict is instantiated. This way
|
or when TypedDict is instantiated. This way
|
||||||
|
@ -2839,10 +2866,11 @@ class _TypedDictMeta(type):
|
||||||
def TypedDict(typename, fields=None, /, *, total=True, **kwargs):
|
def TypedDict(typename, fields=None, /, *, total=True, **kwargs):
|
||||||
"""A simple typed namespace. At runtime it is equivalent to a plain dict.
|
"""A simple typed namespace. At runtime it is equivalent to a plain dict.
|
||||||
|
|
||||||
TypedDict creates a dictionary type that expects all of its
|
TypedDict creates a dictionary type such that a type checker will expect all
|
||||||
instances to have a certain set of keys, where each key is
|
instances to have a certain set of keys, where each key is
|
||||||
associated with a value of a consistent type. This expectation
|
associated with a value of a consistent type. This expectation
|
||||||
is not checked at runtime but is only enforced by type checkers.
|
is not checked at runtime.
|
||||||
|
|
||||||
Usage::
|
Usage::
|
||||||
|
|
||||||
class Point2D(TypedDict):
|
class Point2D(TypedDict):
|
||||||
|
@ -2862,20 +2890,25 @@ def TypedDict(typename, fields=None, /, *, total=True, **kwargs):
|
||||||
Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str})
|
Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str})
|
||||||
|
|
||||||
By default, all keys must be present in a TypedDict. It is possible
|
By default, all keys must be present in a TypedDict. It is possible
|
||||||
to override this by specifying totality.
|
to override this by specifying totality::
|
||||||
Usage::
|
|
||||||
|
|
||||||
class point2D(TypedDict, total=False):
|
class Point2D(TypedDict, total=False):
|
||||||
x: int
|
x: int
|
||||||
y: int
|
y: int
|
||||||
|
|
||||||
This means that a point2D TypedDict can have any of the keys omitted.A type
|
This means that a Point2D TypedDict can have any of the keys omitted. A type
|
||||||
checker is only expected to support a literal False or True as the value of
|
checker is only expected to support a literal False or True as the value of
|
||||||
the total argument. True is the default, and makes all items defined in the
|
the total argument. True is the default, and makes all items defined in the
|
||||||
class body be required.
|
class body be required.
|
||||||
|
|
||||||
The class syntax is only supported in Python 3.6+, while the other
|
The Required and NotRequired special forms can also be used to mark
|
||||||
syntax form works for Python 2.7 and 3.2+
|
individual keys as being required or not required::
|
||||||
|
|
||||||
|
class Point2D(TypedDict):
|
||||||
|
x: int # the "x" key must always be present (Required is the default)
|
||||||
|
y: NotRequired[int] # the "y" key can be omitted
|
||||||
|
|
||||||
|
See PEP 655 for more details on Required and NotRequired.
|
||||||
"""
|
"""
|
||||||
if fields is None:
|
if fields is None:
|
||||||
fields = kwargs
|
fields = kwargs
|
||||||
|
@ -2907,8 +2940,9 @@ TypedDict.__mro_entries__ = lambda bases: (_TypedDict,)
|
||||||
|
|
||||||
@_SpecialForm
|
@_SpecialForm
|
||||||
def Required(self, parameters):
|
def Required(self, parameters):
|
||||||
"""A special typing construct to mark a key of a total=False TypedDict
|
"""Special typing construct to mark a TypedDict key as required.
|
||||||
as required. For example:
|
|
||||||
|
This is mainly useful for total=False TypedDicts. For example::
|
||||||
|
|
||||||
class Movie(TypedDict, total=False):
|
class Movie(TypedDict, total=False):
|
||||||
title: Required[str]
|
title: Required[str]
|
||||||
|
@ -2928,8 +2962,9 @@ def Required(self, parameters):
|
||||||
|
|
||||||
@_SpecialForm
|
@_SpecialForm
|
||||||
def NotRequired(self, parameters):
|
def NotRequired(self, parameters):
|
||||||
"""A special typing construct to mark a key of a TypedDict as
|
"""Special typing construct to mark a TypedDict key as potentially missing.
|
||||||
potentially missing. For example:
|
|
||||||
|
For example::
|
||||||
|
|
||||||
class Movie(TypedDict):
|
class Movie(TypedDict):
|
||||||
title: str
|
title: str
|
||||||
|
@ -2945,8 +2980,9 @@ def NotRequired(self, parameters):
|
||||||
|
|
||||||
|
|
||||||
class NewType:
|
class NewType:
|
||||||
"""NewType creates simple unique types with almost zero
|
"""NewType creates simple unique types with almost zero runtime overhead.
|
||||||
runtime overhead. NewType(name, tp) is considered a subtype of tp
|
|
||||||
|
NewType(name, tp) is considered a subtype of tp
|
||||||
by static type checkers. At runtime, NewType(name, tp) returns
|
by static type checkers. At runtime, NewType(name, tp) returns
|
||||||
a dummy callable that simply returns its argument. Usage::
|
a dummy callable that simply returns its argument. Usage::
|
||||||
|
|
||||||
|
@ -3208,12 +3244,11 @@ def reveal_type[T](obj: T, /) -> T:
|
||||||
x: int = 1
|
x: int = 1
|
||||||
reveal_type(x)
|
reveal_type(x)
|
||||||
|
|
||||||
Running a static type checker (e.g., ``mypy``) on this example
|
Running a static type checker (e.g., mypy) on this example
|
||||||
will produce output similar to 'Revealed type is "builtins.int"'.
|
will produce output similar to 'Revealed type is "builtins.int"'.
|
||||||
|
|
||||||
At runtime, the function prints the runtime type of the
|
At runtime, the function prints the runtime type of the
|
||||||
argument and returns it unchanged.
|
argument and returns it unchanged.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
print(f"Runtime type is {type(obj).__name__!r}", file=sys.stderr)
|
print(f"Runtime type is {type(obj).__name__!r}", file=sys.stderr)
|
||||||
return obj
|
return obj
|
||||||
|
@ -3233,15 +3268,14 @@ def dataclass_transform(
|
||||||
field_specifiers: tuple[type[Any] | Callable[..., Any], ...] = (),
|
field_specifiers: tuple[type[Any] | Callable[..., Any], ...] = (),
|
||||||
**kwargs: Any,
|
**kwargs: Any,
|
||||||
) -> _IdentityCallable:
|
) -> _IdentityCallable:
|
||||||
"""Decorator that marks a function, class, or metaclass as providing
|
"""Decorator to mark an object as providing dataclass-like behaviour.
|
||||||
dataclass-like behavior.
|
|
||||||
|
|
||||||
Example usage with a decorator function:
|
The decorator can be applied to a function, class, or metaclass.
|
||||||
|
|
||||||
T = TypeVar("T")
|
Example usage with a decorator function::
|
||||||
|
|
||||||
@dataclass_transform()
|
@dataclass_transform()
|
||||||
def create_model(cls: type[T]) -> type[T]:
|
def create_model[T](cls: type[T]) -> type[T]:
|
||||||
...
|
...
|
||||||
return cls
|
return cls
|
||||||
|
|
||||||
|
@ -3250,7 +3284,7 @@ def dataclass_transform(
|
||||||
id: int
|
id: int
|
||||||
name: str
|
name: str
|
||||||
|
|
||||||
On a base class:
|
On a base class::
|
||||||
|
|
||||||
@dataclass_transform()
|
@dataclass_transform()
|
||||||
class ModelBase: ...
|
class ModelBase: ...
|
||||||
|
@ -3259,7 +3293,7 @@ def dataclass_transform(
|
||||||
id: int
|
id: int
|
||||||
name: str
|
name: str
|
||||||
|
|
||||||
On a metaclass:
|
On a metaclass::
|
||||||
|
|
||||||
@dataclass_transform()
|
@dataclass_transform()
|
||||||
class ModelMeta(type): ...
|
class ModelMeta(type): ...
|
||||||
|
@ -3315,7 +3349,7 @@ type _Func = Callable[..., Any]
|
||||||
def override[F: _Func](method: F, /) -> F:
|
def override[F: _Func](method: F, /) -> F:
|
||||||
"""Indicate that a method is intended to override a method in a base class.
|
"""Indicate that a method is intended to override a method in a base class.
|
||||||
|
|
||||||
Usage:
|
Usage::
|
||||||
|
|
||||||
class Base:
|
class Base:
|
||||||
def method(self) -> None: ...
|
def method(self) -> None: ...
|
||||||
|
@ -3331,12 +3365,11 @@ def override[F: _Func](method: F, /) -> F:
|
||||||
base class. This helps prevent bugs that may occur when a base class is
|
base class. This helps prevent bugs that may occur when a base class is
|
||||||
changed without an equivalent change to a child class.
|
changed without an equivalent change to a child class.
|
||||||
|
|
||||||
There is no runtime checking of this property. The decorator sets the
|
There is no runtime checking of this property. The decorator attempts to
|
||||||
``__override__`` attribute to ``True`` on the decorated object to allow
|
set the ``__override__`` attribute to ``True`` on the decorated object to
|
||||||
runtime introspection.
|
allow runtime introspection.
|
||||||
|
|
||||||
See PEP 698 for details.
|
See PEP 698 for details.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
method.__override__ = True
|
method.__override__ = True
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue