mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
parent
ddbd4811e4
commit
0d2ed56f6c
1 changed files with 65 additions and 22 deletions
|
@ -2,6 +2,11 @@
|
|||
:mod:`typing` --- Support for type hints
|
||||
========================================
|
||||
|
||||
.. testsetup:: *
|
||||
|
||||
import typing
|
||||
from typing import *
|
||||
|
||||
.. module:: typing
|
||||
:synopsis: Support for type hints (see :pep:`484`).
|
||||
|
||||
|
@ -247,19 +252,22 @@ Callable
|
|||
Frameworks expecting callback functions of specific signatures might be
|
||||
type hinted using ``Callable[[Arg1Type, Arg2Type], ReturnType]``.
|
||||
|
||||
For example::
|
||||
For example:
|
||||
|
||||
.. testcode::
|
||||
|
||||
from collections.abc import Callable
|
||||
|
||||
def feeder(get_next_item: Callable[[], str]) -> None:
|
||||
# Body
|
||||
... # Body
|
||||
|
||||
def async_query(on_success: Callable[[int], None],
|
||||
on_error: Callable[[int, Exception], None]) -> None:
|
||||
# Body
|
||||
... # Body
|
||||
|
||||
async def on_update(value: str) -> None:
|
||||
# Body
|
||||
... # Body
|
||||
|
||||
callback: Callable[[str], Awaitable[None]] = on_update
|
||||
|
||||
It is possible to declare the return type of a callable without specifying
|
||||
|
@ -402,11 +410,14 @@ In this case ``MyDict`` has a single parameter, ``T``.
|
|||
|
||||
Using a generic class without specifying type parameters assumes
|
||||
:data:`Any` for each position. In the following example, ``MyIterable`` is
|
||||
not generic but implicitly inherits from ``Iterable[Any]``::
|
||||
not generic but implicitly inherits from ``Iterable[Any]``:
|
||||
|
||||
.. testcode::
|
||||
|
||||
from collections.abc import Iterable
|
||||
|
||||
class MyIterable(Iterable): # Same as Iterable[Any]
|
||||
...
|
||||
|
||||
User-defined generic type aliases are also supported. Examples::
|
||||
|
||||
|
@ -654,9 +665,11 @@ These can be used as types in annotations and do not support ``[]``.
|
|||
A string created by composing ``LiteralString``-typed objects
|
||||
is also acceptable as a ``LiteralString``.
|
||||
|
||||
Example::
|
||||
Example:
|
||||
|
||||
def run_query(sql: LiteralString) -> ...
|
||||
.. testcode::
|
||||
|
||||
def run_query(sql: LiteralString) -> None:
|
||||
...
|
||||
|
||||
def caller(arbitrary_string: str, literal_string: LiteralString) -> None:
|
||||
|
@ -1450,9 +1463,12 @@ for creating generic types.
|
|||
def __abs__(self) -> "Array[*Shape]": ...
|
||||
def get_shape(self) -> tuple[*Shape]: ...
|
||||
|
||||
Type variable tuples can be happily combined with normal type variables::
|
||||
Type variable tuples can be happily combined with normal type variables:
|
||||
|
||||
.. testcode::
|
||||
|
||||
DType = TypeVar('DType')
|
||||
Shape = TypeVarTuple('Shape')
|
||||
|
||||
class Array(Generic[DType, *Shape]): # This is fine
|
||||
pass
|
||||
|
@ -1460,6 +1476,9 @@ for creating generic types.
|
|||
class Array2(Generic[*Shape, DType]): # This would also be fine
|
||||
pass
|
||||
|
||||
class Height: ...
|
||||
class Width: ...
|
||||
|
||||
float_array_1d: Array[float, Height] = Array() # Totally fine
|
||||
int_array_2d: Array[int, Height, Width] = Array() # Yup, fine too
|
||||
|
||||
|
@ -1904,6 +1923,10 @@ These are not used in annotations. They are building blocks for declaring types.
|
|||
|
||||
A ``TypedDict`` can be generic::
|
||||
|
||||
.. testcode::
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
class Group(TypedDict, Generic[T]):
|
||||
key: T
|
||||
group: list[T]
|
||||
|
@ -1915,7 +1938,9 @@ These are not used in annotations. They are building blocks for declaring types.
|
|||
.. attribute:: __total__
|
||||
|
||||
``Point2D.__total__`` gives the value of the ``total`` argument.
|
||||
Example::
|
||||
Example:
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> from typing import TypedDict
|
||||
>>> class Point2D(TypedDict): pass
|
||||
|
@ -1945,7 +1970,9 @@ These are not used in annotations. They are building blocks for declaring types.
|
|||
non-required keys in the same ``TypedDict`` . This is done by declaring a
|
||||
``TypedDict`` with one value for the ``total`` argument and then
|
||||
inheriting from it in another ``TypedDict`` with a different value for
|
||||
``total``::
|
||||
``total``:
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> class Point2D(TypedDict, total=False):
|
||||
... x: int
|
||||
|
@ -2600,7 +2627,9 @@ Functions and decorators
|
|||
decorated object performs runtime "magic" that
|
||||
transforms a class, giving it :func:`dataclasses.dataclass`-like behaviors.
|
||||
|
||||
Example usage with a decorator function::
|
||||
Example usage with a decorator function:
|
||||
|
||||
.. testcode::
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
|
@ -2705,7 +2734,9 @@ Functions and decorators
|
|||
runtime but should be ignored by a type checker. At runtime, calling
|
||||
a ``@overload``-decorated function directly will raise
|
||||
:exc:`NotImplementedError`. An example of overload that gives a more
|
||||
precise type than can be expressed using a union or a type variable::
|
||||
precise type than can be expressed using a union or a type variable:
|
||||
|
||||
.. testcode::
|
||||
|
||||
@overload
|
||||
def process(response: None) -> None:
|
||||
|
@ -2717,7 +2748,7 @@ Functions and decorators
|
|||
def process(response: bytes) -> str:
|
||||
...
|
||||
def process(response):
|
||||
<actual implementation>
|
||||
... # actual implementation goes here
|
||||
|
||||
See :pep:`484` for more details and comparison with other typing semantics.
|
||||
|
||||
|
@ -2835,14 +2866,16 @@ Introspection helpers
|
|||
|
||||
The function recursively replaces all ``Annotated[T, ...]`` with ``T``,
|
||||
unless ``include_extras`` is set to ``True`` (see :class:`Annotated` for
|
||||
more information). For example::
|
||||
more information). For example:
|
||||
|
||||
.. testcode::
|
||||
|
||||
class Student(NamedTuple):
|
||||
name: Annotated[str, 'some marker']
|
||||
|
||||
get_type_hints(Student) == {'name': str}
|
||||
get_type_hints(Student, include_extras=False) == {'name': str}
|
||||
get_type_hints(Student, include_extras=True) == {
|
||||
assert get_type_hints(Student) == {'name': str}
|
||||
assert get_type_hints(Student, include_extras=False) == {'name': str}
|
||||
assert get_type_hints(Student, include_extras=True) == {
|
||||
'name': Annotated[str, 'some marker']
|
||||
}
|
||||
|
||||
|
@ -2869,7 +2902,9 @@ Introspection helpers
|
|||
If ``X`` is an instance of :class:`ParamSpecArgs` or :class:`ParamSpecKwargs`,
|
||||
return the underlying :class:`ParamSpec`.
|
||||
Return ``None`` for unsupported objects.
|
||||
Examples::
|
||||
Examples:
|
||||
|
||||
.. testcode::
|
||||
|
||||
assert get_origin(str) is None
|
||||
assert get_origin(Dict[str, int]) is dict
|
||||
|
@ -2888,7 +2923,9 @@ Introspection helpers
|
|||
generic type, the order of ``(Y, Z, ...)`` may be different from the order
|
||||
of the original arguments ``[Y, Z, ...]`` due to type caching.
|
||||
Return ``()`` for unsupported objects.
|
||||
Examples::
|
||||
Examples:
|
||||
|
||||
.. testcode::
|
||||
|
||||
assert get_args(int) == ()
|
||||
assert get_args(Dict[int, str]) == (int, str)
|
||||
|
@ -2900,14 +2937,20 @@ Introspection helpers
|
|||
|
||||
Check if a type is a :class:`TypedDict`.
|
||||
|
||||
For example::
|
||||
For example:
|
||||
|
||||
.. testcode::
|
||||
|
||||
class Film(TypedDict):
|
||||
title: str
|
||||
year: int
|
||||
|
||||
is_typeddict(Film) # => True
|
||||
is_typeddict(list | str) # => False
|
||||
assert is_typeddict(Film)
|
||||
assert not is_typeddict(list | str)
|
||||
|
||||
# TypedDict is a factory for creating typed dicts,
|
||||
# not a typed dict itself
|
||||
assert not is_typeddict(TypedDict)
|
||||
|
||||
.. versionadded:: 3.10
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue