Spec-Zone.ru › Python 3.13

typing — Поддержка типов подсказок

Добавлена в версии 3.5.

Исходный код: Lib/typing.py

Примечание

Интерпретатор Python не проверяет типы функций и переменных. Они могут использоваться сторонними инструментами, такими как проверяющие типы, IDE, линтеры и т. д.

Этот модуль предоставляет поддержку типов подсказок во время выполнения.

Рассмотрим функцию ниже:

def surface_area_of_cube(edge_length: float) -> str:
    return f"The surface area of the cube is {6 * edge_length ** 2}."

Функция surface_area_of_cube принимает аргумент, ожидаемый как экземпляр float, как указано подсказкой типа подсказкой типа edge_length: float. Ожидается, что функция вернёт экземпляр str, как указано подсказкой типа -> str.

Хотя подсказки типов могут быть простыми классами, такими как float или str, они также могут быть более сложными. Модуль typing предоставляет словарный запас более продвинутых подсказок типов.

В модуль typing часто добавляются новые возможности. Пакет typing_extensions предоставляет обратные порты этих новых возможностей для более старых версий Python.

См. также

“Список подсказок типов”

Краткий обзор подсказок типов (размещён в документации mypy)

Раздел “Описание системы типов” в документации mypy

Система типов Python стандартизована через PEP, поэтому данное справочное руководство в целом применимо к большинству проверяющих систем типов Python. (Некоторые части могут быть специфичны для mypy.)

“Статическая типизация с Python”

Документация, написанная сообществом, не зависящая от проверяющих систем типов, описывающая особенности системы типов, полезные инструменты для работы с типами и лучшие практики типизации.

Спецификация для системы типов Python

Каноническая, актуальная спецификация системы типов Python находится по адресу “Спецификация системы типов Python”.

Псевдонимы типов

Псевдоним типа определяется с помощью оператора type, который создаёт экземпляр TypeAliasType. В этом примере Vector и list[float] будут обрабатываться как эквивалентные статическими проверяющими типами:

type Vector = list[float]

def scale(scalar: float, vector: Vector) -> Vector:
    return [scalar * num for num in vector]

# passes type checking; a list of floats qualifies as a Vector.
new_vector = scale(2.0, [1.0, -4.2, 5.4])

Псевдонимы типов полезны для упрощения сложных сигнатур типов. Например:

from collections.abc import Sequence

type ConnectionOptions = dict[str, str]
type Address = tuple[str, int]
type Server = tuple[Address, ConnectionOptions]

def broadcast_message(message: str, servers: Sequence[Server]) -> None:
    ...

# The static type checker will treat the previous type signature as
# being exactly equivalent to this one.
def broadcast_message(
    message: str,
    servers: Sequence[tuple[tuple[str, int], dict[str, str]]]
) -> None:
    ...

Оператор type новый в Python 3.12. Для обратной совместимости псевдонимы типов также можно создавать через простое присваивание:

Vector = list[float]

Или пометить с помощью TypeAlias, чтобы сделать явным, что это псевдоним типа, а не обычная переменная:

from typing import TypeAlias

Vector: TypeAlias = list[float]

NewType

Используйте вспомогательную функцию NewType для создания различных типов:

from typing import NewType

UserId = NewType('UserId', int)
some_id = UserId(524313)

Проверяющая система типов будет обрабатывать новый тип так, как если бы он был подклассом исходного типа. Это полезно для обнаружения логических ошибок:

def get_user_name(user_id: UserId) -> str:
    ...

# passes type checking
user_a = get_user_name(UserId(42351))

# fails type checking; an int is not a UserId
user_b = get_user_name(-1)

Вы по-прежнему можете выполнять все int операции над переменной типа UserId, но результат всегда будет типа int. Это позволяет передать UserId там, где ожидается int, но предотвратит случайное создание UserId некорректным способом:

# 'output' is of type 'int', not 'UserId'
output = UserId(23413) + UserId(54341)

Обратите внимание, что эти проверки выполняются только проверяющей системой типов. Во время выполнения оператор Derived = NewType('Derived', Base) сделает Derived вызываемым объектом, который немедленно вернёт переданный ему параметр. Это означает, что выражение Derived(some_value) не создаёт новый класс и не добавляет существенной нагрузки, кроме обычного вызова функции.

Точнее, выражение some_value is Derived(some_value) всегда истинно во время выполнения.

Нельзя создать подтип Derived:

from typing import NewType

UserId = NewType('UserId', int)

# Fails at runtime and does not pass type checking
class AdminUserId(UserId): pass

Однако можно создать NewType на основе «производного» NewType:

from typing import NewType

UserId = NewType('UserId', int)

ProUserId = NewType('ProUserId', UserId)

и проверка типов для ProUserId будет работать как ожидается.

См. PEP 484 для более подробной информации.

Примечание

Вспомните, что использование псевдонима типа объявляет два типа как эквивалентные друг другу. Выполнить type Alias = Original заставит проверяющую систему типов рассматривать Alias как точно эквивалентный Original во всех случаях. Это полезно, когда вы хотите упростить сложные сигнатуры типов.

В отличие от этого, NewType объявляет один тип как подтип другого. Выполнить Derived = NewType('Derived', Original) заставит проверяющую систему типов рассматривать Derived как подкласс Original, что означает, что значение типа Original нельзя использовать там, где ожидается значение типа Derived. Это полезно, когда вы хотите предотвратить логические ошибки с минимальными затратами во время выполнения.

Добавлена в версии 3.5.2.

Изменено в версии 3.10: NewType теперь является классом, а не функцией. В результате при вызове NewType по сравнению с обычной функцией есть дополнительные затраты во время выполнения.

Изменено в версии 3.11: Производительность вызова NewType восстановлена до уровня Python 3.9.

Аннотация вызываемых объектов

Функции — или другие вызываемые объекты — могут быть аннотированы с помощью collections.abc.Callable или устаревшего typing.Callable. Callable[[int], str] обозначает функцию, которая принимает один параметр типа int и возвращает str.

Например:

from collections.abc import Callable, Awaitable

def feeder(get_next_item: Callable[[], str]) -> None:
    ...  # Body

def async_query(on_success: Callable[[int], None],
                on_error: Callable[[int, Exception], None]) -> None:
    ...  # Body

async def on_update(value: str) -> None:
    ...  # Body

callback: Callable[[str], Awaitable[None]] = on_update

Синтаксис подписки всегда должен использоваться ровно с двумя значениями: списком аргументов и типом возвращаемого значения. Список аргументов должен быть списком типов, ParamSpec, Concatenate или эллипсисом. Тип возвращаемого значения должен быть единственным типом.

Если в качестве списка аргументов указан литерал эллипсис ..., это означает, что вызываемый объект с любым произвольным списком параметров будет приемлемым:

def concat(x: str, y: str) -> str:
    return x + y

x: Callable[..., str]
x = str     # OK
x = concat  # Also OK

Callable не может выразить сложные сигнатуры, такие как функции, принимающие переменное число аргументов, перегруженные функции или функции с параметрами только по ключевому слову. Однако эти сигнатуры можно выразить, определив класс Protocol с методом __call__():

from collections.abc import Iterable
from typing import Protocol

class Combiner(Protocol):
    def __call__(self, *vals: bytes, maxlen: int | None = None) -> list[bytes]: ...

def batch_proc(data: Iterable[bytes], cb_results: Combiner) -> bytes:
    for item in data:
        ...

def good_cb(*vals: bytes, maxlen: int | None = None) -> list[bytes]:
    ...
def bad_cb(*vals: bytes, maxitems: int | None) -> list[bytes]:
    ...

batch_proc([], good_cb)  # OK
batch_proc([], bad_cb)   # Error! Argument 2 has incompatible type because of
                         # different name and kind in the callback

Вызываемые объекты, которые принимают другие вызываемые объекты в качестве аргументов, могут указывать, что их типы параметров зависят друг от друга, используя ParamSpec. Кроме того, если вызываемый объект добавляет или удаляет аргументы из других вызываемых объектов, может использоваться оператор Concatenate. Они имеют вид Callable[ParamSpecVariable, ReturnType] и Callable[Concatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable], ReturnType] соответственно.

Изменено в версии 3.10: Callable теперь поддерживает ParamSpec и Concatenate. См. PEP 612 для более подробной информации.

См. также

Документация для ParamSpec и Concatenate содержит примеры использования в Callable.

Обобщения

Поскольку информация о типе объектов, хранящихся в контейнерах, не может быть статически выведена обобщенным способом, многие классы контейнеров в стандартной библиотеке поддерживают подписку для обозначения ожидаемых типов элементов контейнера.

from collections.abc import Mapping, Sequence

class Employee: ...

# Sequence[Employee] indicates that all elements in the sequence
# must be instances of "Employee".
# Mapping[str, str] indicates that all keys and all values in the mapping
# must be strings.
def notify_by_email(employees: Sequence[Employee],
                    overrides: Mapping[str, str]) -> None: ...

Обобщенные функции и классы могут быть параметризованы с использованием синтаксиса параметров типа:

from collections.abc import Sequence

def first[T](l: Sequence[T]) -> T:  # Function is generic over the TypeVar "T"
    return l[0]

Или с использованием фабрики TypeVar напрямую:

from collections.abc import Sequence
from typing import TypeVar

U = TypeVar('U')                  # Declare type variable "U"

def second(l: Sequence[U]) -> U:  # Function is generic over the TypeVar "U"
    return l[1]

Изменено в версии 3.12: Синтаксическая поддержка обобщений является новой в Python 3.12.

Аннотирование кортежей

Для большинства контейнеров в Python система типизации предполагает, что все элементы в контейнере будут одного типа. Например:

from collections.abc import Mapping

# Type checker will infer that all elements in ``x`` are meant to be ints
x: list[int] = []

# Type checker error: ``list`` only accepts a single type argument:
y: list[int, str] = [1, 'foo']

# Type checker will infer that all keys in ``z`` are meant to be strings,
# and that all values in ``z`` are meant to be either strings or ints
z: Mapping[str, str | int] = {}

list принимает только один аргумент типа, поэтому проверка типов выведет ошибку по присваиванию y выше. Аналогично, Mapping принимает только два аргумента типа: первый указывает тип ключей, а второй указывает тип значений.

В отличие от большинства других контейнеров Python, в типичном коде Python часто встречаются кортежи с элементами, не имеющими одинакового типа. По этой причине кортежи имеют специальное обращение в системе типизации Python. tuple принимает любое количество аргументов типа:

# OK: ``x`` is assigned to a tuple of length 1 where the sole element is an int
x: tuple[int] = (5,)

# OK: ``y`` is assigned to a tuple of length 2;
# element 1 is an int, element 2 is a str
y: tuple[int, str] = (5, "foo")

# Error: the type annotation indicates a tuple of length 1,
# but ``z`` has been assigned to a tuple of length 3
z: tuple[int] = (1, 2, 3)

Для обозначения кортежа, который может быть любой длины, и в котором все элементы имеют один и тот же тип T, используйте tuple[T, ...]. Для обозначения пустого кортежа используйте tuple[()]. Использование простого tuple в качестве аннотации эквивалентно использованию tuple[Any, ...]:

x: tuple[int, ...] = (1, 2)
# These reassignments are OK: ``tuple[int, ...]`` indicates x can be of any length
x = (1, 2, 3)
x = ()
# This reassignment is an error: all elements in ``x`` must be ints
x = ("foo", "bar")

# ``y`` can only ever be assigned to an empty tuple
y: tuple[()] = ()

z: tuple = ("foo", "bar")
# These reassignments are OK: plain ``tuple`` is equivalent to ``tuple[Any, ...]``
z = (1, 2, 3)
z = ()

Тип объектов класса

Переменная, аннотированная с C может принять значение типа C. В противоположность этому, переменная, аннотированная с type[C] (или устаревшая typing.Type[C]) может принять значения, являющиеся самими классами — конкретно, она примет объект класса C. Например:

a = 3         # Has type ``int``
b = int       # Has type ``type[int]``
c = type(a)   # Also has type ``type[int]``

Обратите внимание, что type[C] является ковариативным:

class User: ...
class ProUser(User): ...
class TeamUser(User): ...

def make_new_user(user_class: type[User]) -> User:
    # ...
    return user_class()

make_new_user(User)      # OK
make_new_user(ProUser)   # Also OK: ``type[ProUser]`` is a subtype of ``type[User]``
make_new_user(TeamUser)  # Still fine
make_new_user(User())    # Error: expected ``type[User]`` but got ``User``
make_new_user(int)       # Error: ``type[int]`` is not a subtype of ``type[User]``

Единственными допустимыми параметрами для type являются классы, Any, переменные типа и объединения любых из этих типов. Например:

def new_non_team_user(user_class: type[BasicUser | ProUser]): ...

new_non_team_user(BasicUser)  # OK
new_non_team_user(ProUser)    # OK
new_non_team_user(TeamUser)   # Error: ``type[TeamUser]`` is not a subtype
                              # of ``type[BasicUser | ProUser]``
new_non_team_user(User)       # Also an error

type[Any] эквивалентно type, которое является корнем иерархии метаклассов Python.

Аннотирование генераторов и корутин

Генератор может быть аннотирован с использованием обобщенного типа Generator[YieldType, SendType, ReturnType]. Например:

def echo_round() -> Generator[int, float, str]:
    sent = yield 0
    while sent >= 0:
        sent = yield round(sent)
    return 'Done'

Обратите внимание, что в отличие от многих других обобщенных классов в стандартной библиотеке, поведение SendType Generator является контравариантным, а не ковариативным или инвариантным.

Параметры SendType и ReturnType по умолчанию равны None:

def infinite_stream(start: int) -> Generator[int]:
    while True:
        yield start
        start += 1

Также возможно установить эти типы явно:

def infinite_stream(start: int) -> Generator[int, None, None]:
    while True:
        yield start
        start += 1

Простые генераторы, которые всегда возвращают только значения, также могут быть аннотированы как имеющие возвращаемый тип либо Iterable[YieldType], либо Iterator[YieldType]:

def infinite_stream(start: int) -> Iterator[int]:
    while True:
        yield start
        start += 1

Асинхронные генераторы обрабатываются аналогичным образом, но не ожидайте аргумента типа ReturnType (AsyncGenerator[YieldType, SendType]). Аргумент SendType по умолчанию равен None, поэтому следующие определения эквивалентны:

async def infinite_stream(start: int) -> AsyncGenerator[int]:
    while True:
        yield start
        start = await increment(start)

async def infinite_stream(start: int) -> AsyncGenerator[int, None]:
    while True:
        yield start
        start = await increment(start)

Как и в синхронном случае, AsyncIterable[YieldType] и AsyncIterator[YieldType] также доступны:

async def infinite_stream(start: int) -> AsyncIterator[int]:
    while True:
        yield start
        start = await increment(start)

Корутины могут быть аннотированы с помощью Coroutine[YieldType, SendType, ReturnType]. Аргументы обобщений соответствуют аргументам Generator, например:

from collections.abc import Coroutine
c: Coroutine[list[str], str, int]  # Some coroutine defined elsewhere
x = c.send('hi')                   # Inferred type of 'x' is list[str]
async def bar() -> None:
    y = await c                    # Inferred type of 'y' is int

Пользовательские обобщенные типы

Пользовательский класс может быть определен как обобщенный класс.

from logging import Logger

class LoggedVar[T]:
    def __init__(self, value: T, name: str, logger: Logger) -> None:
        self.name = name
        self.logger = logger
        self.value = value

    def set(self, new: T) -> None:
        self.log('Set ' + repr(self.value))
        self.value = new

    def get(self) -> T:
        self.log('Get ' + repr(self.value))
        return self.value

    def log(self, message: str) -> None:
        self.logger.info('%s: %s', self.name, message)

Этот синтаксис указывает, что класс LoggedVar параметризован по одному переменной типа T . Это также делает T допустимым типом внутри тела класса.

Обобщенные классы неявно наследуют от Generic. Для совместимости с Python 3.11 и ниже, также возможно явно унаследовать от Generic для обозначения обобщенного класса:

from typing import TypeVar, Generic

T = TypeVar('T')

class LoggedVar(Generic[T]):
    ...

Обобщенные классы имеют __class_getitem__() методы, что означает, что они могут быть параметризованы во время выполнения (например, LoggedVar[int] ниже):

from collections.abc import Iterable

def zero_all_vars(vars: Iterable[LoggedVar[int]]) -> None:
    for var in vars:
        var.set(0)

Обобщенный тип может иметь любое количество переменных типа. Все разновидности TypeVar допустимы в качестве параметров обобщенного типа:

from typing import TypeVar, Generic, Sequence

class WeirdTrio[T, B: Sequence[bytes], S: (int, str)]:
    ...

OldT = TypeVar('OldT', contravariant=True)
OldB = TypeVar('OldB', bound=Sequence[bytes], covariant=True)
OldS = TypeVar('OldS', int, str)

class OldWeirdTrio(Generic[OldT, OldB, OldS]):
    ...

Каждый аргумент переменной типа для Generic должен быть уникальным. Поэтому следующее недопустимо:

from typing import TypeVar, Generic
...

class Pair[M, M]:  # SyntaxError
    ...

T = TypeVar('T')

class Pair(Generic[T, T]):   # INVALID
    ...

Обобщенные классы также могут наследоваться от других классов:

from collections.abc import Sized

class LinkedList[T](Sized):
    ...

При наследовании от обобщенных классов некоторые параметры типа могут быть фиксированы:

from collections.abc import Mapping

class MyDict[T](Mapping[str, T]):
    ...

В этом случае MyDict имеет один параметр T.

Использование обобщенного класса без указания параметров типа предполагает Any для каждой позиции. В следующем примере MyIterable не является обобщенным, но неявно наследуется от Iterable[Any]:

from collections.abc import Iterable

class MyIterable(Iterable): # Same as Iterable[Any]
    ...

Также поддерживаются пользовательские обобщенные алиасы типов. Примеры:

from collections.abc import Iterable

type Response[S] = Iterable[S] | int

# Return type here is same as Iterable[str] | int
def response(query: str) -> Response[str]:
    ...

type Vec[T] = Iterable[tuple[T, T]]

def inproduct[T: (int, float, complex)](v: Vec[T]) -> T: # Same as Iterable[tuple[T, T]]
    return sum(x*y for x, y in v)

Для обратной совместимости обобщенные алиасы типов также могут быть созданы с помощью простого присваивания:

from collections.abc import Iterable
from typing import TypeVar

S = TypeVar("S")
Response = Iterable[S] | int

Изменено в версии 3.7: Generic больше не имеет пользовательского метакласса.

Изменено в версии 3.12: Синтаксическая поддержка обобщений и алиасов типов новая в версии 3.12. Ранее обобщенные классы должны были явно наследоваться от Generic или содержать переменную типа в одном из своих базовых классов.

Пользовательские обобщения для выражений параметров также поддерживаются через переменные параметров спецификации в формате [**P]. Поведение согласуется с описанными выше переменными типа, так как модуль typing обрабатывает переменные спецификации параметров как специализированную переменную типа. Исключением является то, что список типов может быть использован для подстановки ParamSpec:

>>> class Z[T, **P]: ...  # T is a TypeVar; P is a ParamSpec
...
>>> Z[int, [dict, float]]
__main__.Z[int, [dict, float]]

Классы, обобщенные по ParamSpec, также могут быть созданы с помощью явного наследования от Generic. В этом случае ** не используется:

from typing import ParamSpec, Generic

P = ParamSpec('P')

class Z(Generic[P]):
    ...

Другое отличие между TypeVar и ParamSpec заключается в том, что обобщение с одной переменной спецификации параметров будет принимать списки параметров в форматах X[[Type1, Type2, ...]] и также X[Type1, Type2, ...] по эстетическим соображениям. Внутренне последний преобразуется в первый, поэтому следующие выражения эквивалентны:

>>> class X[**P]: ...
...
>>> X[int, str]
__main__.X[[int, str]]
>>> X[[int, str]]
__main__.X[[int, str]]

Обратите внимание, что обобщения с ParamSpec могут не иметь правильного __parameters__ после подстановки в некоторых случаях, так как они предназначены в первую очередь для статической проверки типов.

Изменено в версии 3.10: Generic теперь может быть параметризован по выражениям параметров. См. ParamSpec и PEP 612 для получения дополнительной информации.

Пользовательский обобщенный класс может иметь ABC в качестве базовых классов без конфликтов метаклассов. Обобщенные метаклассы не поддерживаются. Результат параметризации обобщений кэшируется, и большинство типов в модуле typing являются хешируемыми и сравнимыми для равенства.

Тип Any

Особый вид типа — Any. Статический проверяющий типов будет обрабатывать каждый тип как совместимый с Any, и Any как совместимые со всеми типами.

Это означает, что можно выполнить любую операцию или вызов метода на значении типа Any и присвоить его любой переменной:

from typing import Any

a: Any = None
a = []          # OK
a = 2           # OK

s: str = ''
s = a           # OK

def foo(item: Any) -> int:
    # Passes type checking; 'item' could be any type,
    # and that type might have a 'bar' method
    item.bar()
    ...

Обратите внимание, что проверка типов не выполняется при присваивании значения типа Any более точному типу. Например, статическая проверка типов не сообщила об ошибке при присваивании a к s, хотя s было объявлено как тип str и получает значение int во время выполнения!

Кроме того, все функции без типа возвращаемого значения или типов параметров неявно будут использовать Any:

def legacy_parser(text):
    ...
    return data

# A static type checker will treat the above
# as having the same signature as:
def legacy_parser(text: Any) -> Any:
    ...
    return data

Это поведение позволяет Any использоваться как "выход", когда нужно объединить динамический и статический типы.

Сравните поведение Any с поведением object. Подобно Any, каждый тип является подтипом object. Однако, в отличие от Any, обратное неверно: object не является подтипом каждого другого типа.

Это означает, что когда тип значения — object, проверяющий типов отклонит почти все операции над ним, а присвоение его переменной (или использование в качестве возвращаемого значения) более специализированного типа — это ошибка типа. Например:

def hash_a(item: object) -> int:
    # Fails type checking; an object does not have a 'magic' method.
    item.magic()
    ...

def hash_b(item: Any) -> int:
    # Passes type checking
    item.magic()
    ...

# Passes type checking, since ints and strs are subclasses of object
hash_a(42)
hash_a("foo")

# Passes type checking, since Any is compatible with all types
hash_b(42)
hash_b("foo")

Используйте object для указания того, что значение может быть любым типом безопасным способом. Используйте Any для указания того, что значение имеет динамический тип.

Номинальный против структурного подтипирования

Изначально PEP 484 определил систему статического типирования Python как использующую номинальное подтипирование. Это означает, что класс A разрешен там, где ожидается класс B только в том случае, если A является подклассом B.

Это требование ранее также применялось к абстрактным базовым классам, таким как Iterable. Проблема с этим подходом заключается в том, что класс должен был быть явно помечен для их поддержки, что нетипично для Python и отличается от того, что обычно делается в образцовом динамически типизированном коде Python. Например, это соответствует PEP 484:

from collections.abc import Sized, Iterable, Iterator

class Bucket(Sized, Iterable[int]):
    ...
    def __len__(self) -> int: ...
    def __iter__(self) -> Iterator[int]: ...

PEP 544 позволяет решить эту проблему, позволяя пользователям писать вышеуказанный код без явных базовых классов в определении класса, что позволяет статическим проверяющим типов неявно рассматривать Bucket как подтип как Sized , так и Iterable[int]. Это известно как структурное подтипирование (или статический "уткотип"):

from collections.abc import Iterator, Iterable

class Bucket:  # Note: no base classes
    ...
    def __len__(self) -> int: ...
    def __iter__(self) -> Iterator[int]: ...

def collect(items: Iterable[int]) -> int: ...
result = collect(Bucket())  # Passes type check

Кроме того, унаследуя от специального класса Protocol, пользователь может определять новые пользовательские протоколы, чтобы полностью насладиться структурным подтипированием (см. примеры ниже).

END_OF_DOCUMENT_MARKER

Содержание модуля

Модуль typing определяет следующие классы, функции и декораторы.

Специальные примитивы типизации

Специальные типы

Эти типы могут быть использованы в качестве типов в аннотациях. Они не поддерживают подписку с использованием [].

typing.Any

Специальный тип, обозначающий не ограниченный тип.

  • Каждый тип совместим с Any.
  • Any совместим с любым типом.

Изменено в версии 3.11: Any теперь может использоваться в качестве базового класса. Это может быть полезно для предотвращения ошибок проверки типов с классами, которые могут реализовывать интерфейс в любой точке или являются высокодинамичными.

typing.AnyStr

Переменная типа, ограниченная типами ограниченных переменных типа.

Определение:

AnyStr = TypeVar('AnyStr', str, bytes)

AnyStr предназначен для использования в функциях, которые могут принимать аргументы str или bytes, но не могут допускать их смешивание.

Например:

def concat(a: AnyStr, b: AnyStr) -> AnyStr:
    return a + b

concat("foo", "bar")    # OK, output has type 'str'
concat(b"foo", b"bar")  # OK, output has type 'bytes'
concat("foo", b"bar")   # Error, cannot mix str and bytes

Обратите внимание, что, несмотря на свое название, AnyStr не имеет никакого отношения к типу Any, и не означает «любая строка». В частности, AnyStr и str | bytes различны и имеют разные области применения:

# Invalid use of AnyStr:
# The type variable is used only once in the function signature,
# so cannot be "solved" by the type checker
def greet_bad(cond: bool) -> AnyStr:
    return "hi there!" if cond else b"greetings!"

# The better way of annotating this function:
def greet_proper(cond: bool) -> str | bytes:
    return "hi there!" if cond else b"greetings!"

Устаревшее начиная с версии 3.13, будет удалено в версии 3.18: Устарело в пользу новой синтаксической конструкции параметров типа. Используйте class A[T: (str, bytes)]: ... вместо импорта AnyStr. См. PEP 695 для получения дополнительных сведений.

В Python 3.16 AnyStr будет удалено из typing.__all__, и предупреждения об устаревании будут выводиться во время выполнения при доступе или импорте из typing. AnyStr будет удалено из typing в Python 3.18.

typing.LiteralString

Специальный тип, включающий только строковые литералы.

Любой строковый литерал совместим с LiteralString, а также другой LiteralString. Однако объект, типизированный только как str , несовместим. Строка, созданная путём конкатенации объектов типа LiteralString, также принимается как LiteralString.

Пример:

def run_query(sql: LiteralString) -> None:
    ...

def caller(arbitrary_string: str, literal_string: LiteralString) -> None:
    run_query("SELECT * FROM students")  # OK
    run_query(literal_string)  # OK
    run_query("SELECT * FROM " + literal_string)  # OK
    run_query(arbitrary_string)  # type checker error
    run_query(  # type checker error
        f"SELECT * FROM students WHERE name = {arbitrary_string}"
    )

LiteralString полезен для чувствительных API, где произвольные строки, сгенерированные пользователем, могут привести к проблемам. Например, два вышеприведённых случая, которые генерируют ошибки проверки типов, могут быть уязвимы к атаке SQL-инъекций.

См. PEP 675 для получения дополнительных сведений.

Добавлен в версии 3.11.

typing.Never
typing.NoReturn

Never и NoReturn представляют собой тип-дно, тип, у которого нет элементов.

Они могут использоваться для указания того, что функция никогда не возвращает результат, например, sys.exit():

from typing import Never  # or NoReturn

def stop() -> Never:
    raise RuntimeError('no way')

Или для определения функции, которая никогда не должна вызываться, так как у нее нет допустимых аргументов, например, assert_never():

from typing import Never  # or NoReturn

def never_call_me(arg: Never) -> None:
    pass

def int_or_str(arg: int | str) -> None:
    never_call_me(arg)  # type checker error
    match arg:
        case int():
            print("It's an int")
        case str():
            print("It's a str")
        case _:
            never_call_me(arg)  # OK, arg is of type Never (or NoReturn)

Never и NoReturn имеют одинаковое значение в системе типов, и статические анализаторы типов обрабатывают их одинаково.

Добавлен в версии 3.6.2: Добавлен NoReturn.

Добавлен в версии 3.11: Добавлен Never.

typing.Self

Специальный тип для представления текущего вложенного класса.

Например:

from typing import Self, reveal_type

class Foo:
    def return_self(self) -> Self:
        ...
        return self

class SubclassOfFoo(Foo): pass

reveal_type(Foo().return_self())  # Revealed type is "Foo"
reveal_type(SubclassOfFoo().return_self())  # Revealed type is "SubclassOfFoo"

Эта аннотация семантически эквивалентна следующему, но более лаконична:

from typing import TypeVar

Self = TypeVar("Self", bound="Foo")

class Foo:
    def return_self(self: Self) -> Self:
        ...
        return self

В общем случае, если что-то возвращает self, как в примерах выше, вы должны использовать Self в качестве аннотации возвращаемого значения. Если Foo.return_self была анотирована как возвращающая "Foo", тогда анализатор типов определит возвращаемый объект из SubclassOfFoo.return_self как имеющий тип Foo , а не SubclassOfFoo.

Другие распространённые случаи использования включают:

  • classmethod, которые используются как альтернативные конструкторы и возвращают экземпляры параметра cls.
  • Анотирование метода __enter__(), который возвращает self.

Вы не должны использовать Self в качестве аннотации возвращаемого значения, если метод не гарантирует возвращение экземпляра подкласса при наследовании класса:

class Eggs:
    # Self would be an incorrect return annotation here,
    # as the object returned is always an instance of Eggs,
    # even in subclasses
    def returns_eggs(self) -> "Eggs":
        return Eggs()

См. PEP 673 для получения дополнительных сведений.

Добавлен в версии 3.11.

typing.TypeAlias

Специальная аннотация для явного объявления псевдонима типа.

Например:

from typing import TypeAlias

Factors: TypeAlias = list[int]

TypeAlias особенно полезно в старых версиях Python для аннотирования псевдонимов, которые используют ссылки вперёд, так как анализаторам типов может быть трудно отличить их от обычных присваиваний переменных:

from typing import Generic, TypeAlias, TypeVar

T = TypeVar("T")

# "Box" does not exist yet,
# so we have to use quotes for the forward reference on Python <3.12.
# Using ``TypeAlias`` tells the type checker that this is a type alias declaration,
# not a variable assignment to a string.
BoxOfStrings: TypeAlias = "Box[str]"

class Box(Generic[T]):
    @classmethod
    def make_box_of_strings(cls) -> BoxOfStrings: ...

См. PEP 613 для получения дополнительных сведений.

Добавлен в версии 3.10.

Устарело начиная с версии 3.12: TypeAlias устарело в пользу оператора type, который создаёт экземпляры TypeAliasType и который нативно поддерживает ссылки вперёд. Обратите внимание, что хотя TypeAlias и TypeAliasType служат аналогичным целям и имеют аналогичные названия, они различаются, и последний не является типом первого. Удаление TypeAlias в настоящее время не планируется, но пользователям рекомендуется перейти на операторы type.

Специальные формы

Эти формы могут использоваться как типы в аннотациях. Все они поддерживают подписку с помощью [], но каждая имеет уникальный синтаксис.

typing.Union

Тип объединения; Union[X, Y] эквивалентно X | Y и означает либо X, либо Y.

Для определения объединения используйте, например, Union[int, str] или сокращённую запись int | str. Использование сокращённой записи рекомендуется. Подробности:

  • Аргументы должны быть типами, и их должно быть как минимум один.
  • Объединения объединений сжимаются, например:

    Union[Union[int, str], float] == Union[int, str, float]
    
  • Объединения с одним аргументом исчезают, например:

    Union[int] == int  # The constructor actually returns int
    
  • Избыточные аргументы пропускаются, например:

    Union[int, str, int] == Union[int, str] == int | str
    
  • При сравнении объединений порядок аргументов игнорируется, например:

    Union[int, str] == Union[str, int]
    
  • Вы не можете создавать подклассы или экземпляры типа Union.
  • Вы не можете записать Union[X][Y].

Изменено в версии 3.7: Не удаляйте явные подклассы из объединений во время выполнения.

Изменено в версии 3.10: Объединения теперь можно записать как X | Y. См. выражения типа объединения.

typing.Optional

Optional[X] эквивалентно X | None (или Union[X, None]).

Обратите внимание, что это не то же самое, что необязательный аргумент, имеющий значение по умолчанию. Для необязательного аргумента со значением по умолчанию не требуется квалификатор Optional в аннотации типа, просто потому, что он необязателен. Например:

def foo(arg: int = 0) -> None:
    ...

С другой стороны, если явно разрешено значение None использование Optional уместно, независимо от того, является ли аргумент необязательным или нет. Например:

def foo(arg: Optional[int] = None) -> None:
    ...

Изменено в версии 3.10: Optional теперь можно записать как X | None. См. выражения типа объединения.

typing.Concatenate

Специальная форма для аннотирования функций высшего порядка.

Concatenate может использоваться в сочетании с Callable и ParamSpec для аннотации вызова высшего порядка, который добавляет, удаляет или преобразует параметры другого вызова. Использование в форме Concatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable]. Concatenate в настоящее время допустимо только в качестве первого аргумента к Callable. Последний параметр для Concatenate должен быть ParamSpec или многоточие (...).

Например, для аннотации декоратора with_lock , предоставляющего threading.Lock декорированной функции, Concatenate можно использовать для указания того, что with_lock ожидает вызов, который принимает в качестве первого аргумента Lock и возвращает вызов с другой сигнатурой типа. В этом случае ParamSpec указывает, что типы параметров возвращаемого вызова зависят от типов параметров передаваемого вызова:

from collections.abc import Callable
from threading import Lock
from typing import Concatenate

# Use this lock to ensure that only one thread is executing a function
# at any time.
my_lock = Lock()

def with_lock[**P, R](f: Callable[Concatenate[Lock, P], R]) -> Callable[P, R]:
    '''A type-safe decorator which provides a lock.'''
    def inner(*args: P.args, **kwargs: P.kwargs) -> R:
        # Provide the lock as the first argument.
        return f(my_lock, *args, **kwargs)
    return inner

@with_lock
def sum_threadsafe(lock: Lock, numbers: list[float]) -> float:
    '''Add a list of numbers together in a thread-safe manner.'''
    with lock:
        return sum(numbers)

# We don't need to pass in the lock ourselves thanks to the decorator.
sum_threadsafe([1.1, 2.2, 3.3])

Добавлен в версии 3.10.

См. также

  • PEP 612 – Переменные спецификации параметров (PEP, который представил ParamSpec и Concatenate)
  • ParamSpec
  • Аннотирование вызываемых объектов
typing.Literal

Специальная форма типизации для определения «литеральных типов».

Literal можно использовать, чтобы указать проверкам типов, что аннотированный объект имеет значение, эквивалентное одному из указанных литералов.

Например:

def validate_simple(data: Any) -> Literal[True]:  # always returns True
    ...

type Mode = Literal['r', 'rb', 'w', 'wb']
def open_helper(file: str, mode: Mode) -> str:
    ...

open_helper('/some/path', 'r')      # Passes type check
open_helper('/other/path', 'typo')  # Error in type checker

Literal[...] не может быть подклассом. Во время выполнения произвольное значение разрешено в качестве аргумента типа для Literal[...], но проверки типов могут наложить ограничения. См. PEP 586 для получения более подробной информации о литеральных типах.

Добавлен в версии 3.8.

Изменено в версии 3.9.1: Literal теперь удаляет дубликаты параметров. Сравнения на равенство объектов Literal больше не зависят от порядка. Объекты Literal теперь будут генерировать исключение TypeError при сравнении на равенство, если один из их параметров не является хешируемым.

typing.ClassVar

Специальная конструкция типа для маркировки переменных класса.

Как введено в PEP 526, аннотация переменной, заключенная в ClassVar, указывает, что данный атрибут предназначен для использования в качестве переменной класса и не должен устанавливаться на экземплярах этого класса. Использование:

class Starship:
    stats: ClassVar[dict[str, int]] = {} # class variable
    damage: int = 10                     # instance variable

ClassVar принимает только типы и не может быть дополнительно подписывается.

ClassVar не является классом и не должна использоваться с isinstance() или issubclass(). ClassVar не изменяет поведение Python во время выполнения, но может использоваться сторонними проверками типов. Например, проверка типов может отметить следующий код как ошибку:

enterprise_d = Starship(3000)
enterprise_d.stats = {} # Error, setting class variable on instance
Starship.stats = {}     # This is OK

Добавлен в версии 3.5.3.

Изменено в версии 3.13: ClassVar теперь может быть вложен в Final и наоборот.

typing.Final

Специальная конструкция типизации для указания конечных имен для проверок типов.

Имена Final не могут быть переназначены ни в каком объёме. Объявленные в области класса имена Final не могут быть переопределены в подклассах.

Например:

MAX_SIZE: Final = 9000
MAX_SIZE += 1  # Error reported by type checker

class Connection:
    TIMEOUT: Final[int] = 10

class FastConnector(Connection):
    TIMEOUT = 1  # Error reported by type checker

Проверки этих свойств во время выполнения нет. См. PEP 591 для получения более подробной информации.

Добавлен в версии 3.8.

Изменено в версии 3.13: Final теперь может быть вложен в ClassVar и наоборот.

typing.Required

Специальная конструкция типизации для маркировки ключа TypedDict как обязательного.

Это в основном полезно для total=False TypedDicts. См. TypedDict и PEP 655 для получения дополнительной информации.

Добавлен в версии 3.11.

typing.NotRequired

Специальная конструкция типизации для маркировки ключа TypedDict как потенциально отсутствующего.

См. TypedDict и PEP 655 для получения дополнительной информации.

Добавлен в версии 3.11.

typing.ReadOnly

Специальная конструкция типизации для маркировки элемента TypedDict как только для чтения.

Например:

class Movie(TypedDict):
   title: ReadOnly[str]
   year: int

def mutate_movie(m: Movie) -> None:
   m["year"] = 1999  # allowed
   m["title"] = "The Matrix"  # typechecker error

Нет проверки этого свойства во время выполнения.

См. TypedDict и PEP 705 для получения дополнительной информации.

Добавлен в версии 3.13.

typing.Annotated

Специальная форма типизации для добавления метаданных, специфичных для контекста, к аннотации.

Добавьте метаданные x к заданному типу T с помощью аннотации Annotated[T, x]. Метаданные, добавленные с помощью Annotated, могут использоваться инструментами статического анализа или во время выполнения. Во время выполнения метаданные хранятся в атрибуте __metadata__.

Если библиотека или инструмент сталкиваются с аннотацией Annotated[T, x] и не имеют специальной логики для метаданных, они должны игнорировать метаданные и просто рассматривать аннотацию как T. Таким образом, Annotated может быть полезным для кода, который хочет использовать аннотации для целей, выходящих за рамки системы статической типизации Python.

Использование Annotated[T, x] в качестве аннотации всё ещё позволяет проводить статическую проверку типов T, так как инструменты проверки типов просто проигнорируют метаданные x. Таким образом, Annotated отличается от декоратора @no_type_check, который также можно использовать для добавления аннотаций за пределами системы типизации, но полностью отключает проверку типов для функции или класса.

Ответственность за интерпретацию метаданных лежит на инструменте или библиотеке, столкнувшейся с аннотацией Annotated. Инструмент или библиотека, сталкиваясь с типом Annotated, могут просмотреть элементы метаданных, чтобы определить, представляют ли они интерес (например, с помощью isinstance()).

Annotated[<type>, <metadata>]

Вот пример того, как вы можете использовать Annotated для добавления метаданных к аннотациям типов, если вы выполняете анализ диапазона:

@dataclass
class ValueRange:
    lo: int
    hi: int

T1 = Annotated[int, ValueRange(-10, 5)]
T2 = Annotated[T1, ValueRange(-20, 3)]

Подробности синтаксиса:

  • Первый аргумент Annotated должен быть допустимым типом
  • Можно предоставить несколько элементов метаданных (Annotated поддерживает аргументы с переменным числом значений):

    @dataclass
    class ctype:
        kind: str
    
    Annotated[int, ValueRange(3, 10), ctype("char")]
    

    Инструмент, потребляющий аннотации, решает, разрешено ли клиенту добавлять несколько элементов метаданных к одной аннотации, и как объединять эти аннотации.

  • Annotated должен быть индексирован не менее чем двумя аргументами (Annotated[int] недействителен)
  • Порядок элементов метаданных сохраняется и имеет значение для проверок равенства:

    assert Annotated[int, ValueRange(3, 10), ctype("char")] != Annotated[
        int, ctype("char"), ValueRange(3, 10)
    ]
    
  • Вложенные типы Annotated сглаживаются. Порядок элементов метаданных начинается с самой внутренней аннотации:

    assert Annotated[Annotated[int, ValueRange(3, 10)], ctype("char")] == Annotated[
        int, ValueRange(3, 10), ctype("char")
    ]
    
  • Дублирующиеся элементы метаданных не удаляются:

    assert Annotated[int, ValueRange(3, 10)] != Annotated[
        int, ValueRange(3, 10), ValueRange(3, 10)
    ]
    
  • Annotated может использоваться с вложенными и обобщёнными псевдонимами:

    @dataclass
    class MaxLen:
        value: int
    
    type Vec[T] = Annotated[list[tuple[T, T]], MaxLen(10)]
    
    # When used in a type annotation, a type checker will treat "V" the same as
    # ``Annotated[list[tuple[int, int]], MaxLen(10)]``:
    type V = Vec[int]
    
  • Annotated нельзя использовать с распакованным TypeVarTuple:

    type Variadic[*Ts] = Annotated[*Ts, Ann1]  # NOT valid
    

    Это будет эквивалентно:

    Annotated[T1, T2, T3, ..., Ann1]
    

    где T1, T2, и т. д. являются TypeVars. Это было бы неверно: только один тип должен быть передан в Annotated.

  • По умолчанию, get_type_hints() удаляет метаданные из аннотаций. Передайте include_extras=True для сохранения метаданных:

    >>> from typing import Annotated, get_type_hints
    >>> def func(x: Annotated[int, "metadata"]) -> None: pass
    ...
    >>> get_type_hints(func)
    {'x': <class 'int'>, 'return': <class 'NoneType'>}
    >>> get_type_hints(func, include_extras=True)
    {'x': typing.Annotated[int, 'metadata'], 'return': <class 'NoneType'>}
    
  • Во время выполнения метаданные, связанные с типом Annotated, могут быть получены через атрибут __metadata__:

    >>> from typing import Annotated
    >>> X = Annotated[int, "very", "important", "metadata"]
    >>> X
    typing.Annotated[int, 'very', 'important', 'metadata']
    >>> X.__metadata__
    ('very', 'important', 'metadata')
    
  • Во время выполнения, если вы хотите получить исходный тип, обернутый в Annotated, используйте атрибут __origin__:

    >>> from typing import Annotated, get_origin
    >>> Password = Annotated[str, "secret"]
    >>> Password.__origin__
    <class 'str'>
    

    Обратите внимание, что использование get_origin() вернёт Annotated само:

    >>> get_origin(Password)
    typing.Annotated
    

См. также

PEP 593 - Гибкие аннотации функций и переменных

PEP, вводящий Annotated в стандартную библиотеку.

Добавлена в версии 3.9.

typing.TypeIs

Специальная конструкция типизации для маркирования пользовательских функций-предикатов типов.

TypeIs может использоваться для аннотации возвращаемого типа пользовательской функции-предиката типа. TypeIs принимает только один аргумент типа. Во время выполнения функции, помеченные таким образом, должны возвращать булево значение и принимать как минимум один позиционный аргумент.

TypeIs предназначен для улучшения сужения типов — техники, используемой инструментами статической типизации для определения более точного типа выражения в потоке кода программы. Обычно сужение типов выполняется путем анализа условного потока кода и применения сужения к блоку кода. Условное выражение здесь иногда называется «предикатом типа»:

def is_str(val: str | float):
    # "isinstance" type predicate
    if isinstance(val, str):
        # Type of ``val`` is narrowed to ``str``
        ...
    else:
        # Else, type of ``val`` is narrowed to ``float``.
        ...

Иногда удобно использовать пользовательскую булеву функцию в качестве предиката типа. Такая функция должна использовать TypeIs[...] или TypeGuard в качестве типа возвращаемого значения, чтобы сообщить инструментам статической типизации об этом намерении. TypeIs обычно имеет более интуитивное поведение, чем TypeGuard, но его нельзя использовать, когда типы входных и выходных данных несовместимы (например, list[object] в list[int] ) или когда функция не возвращает True для всех экземпляров сужаемого типа.

Использование -> TypeIs[NarrowedType] сообщает инструменту статической типизации, что для данной функции:

  1. Значение возврата является булевым.
  2. Если возвращаемое значение True, тип его аргумента — это пересечение исходного типа аргумента и NarrowedType.
  3. Если возвращаемое значение False, тип его аргумента сужается, исключая NarrowedType.

Например:

from typing import assert_type, final, TypeIs

class Parent: pass
class Child(Parent): pass
@final
class Unrelated: pass

def is_parent(val: object) -> TypeIs[Parent]:
    return isinstance(val, Parent)

def run(arg: Child | Unrelated):
    if is_parent(arg):
        # Type of ``arg`` is narrowed to the intersection
        # of ``Parent`` and ``Child``, which is equivalent to
        # ``Child``.
        assert_type(arg, Child)
    else:
        # Type of ``arg`` is narrowed to exclude ``Parent``,
        # so only ``Unrelated`` is left.
        assert_type(arg, Unrelated)

Тип внутри TypeIs должен соответствовать типу аргумента функции; в противном случае инструменты статической типизации выдадут ошибку. Неправильно написанная функция TypeIs может привести к некорректному поведению системы типов; ответственность за безопасное с точки зрения типов написание таких функций лежит на пользователе.

Если функция TypeIs является методом класса или экземпляра, то тип в TypeIs соответствует типу второго параметра (после cls или self).

Короче говоря, форма def foo(arg: TypeA) -> TypeIs[TypeB]: ..., означает, что если foo(arg) возвращает True, то arg является экземпляром TypeB, а если возвращает False, то не является экземпляром TypeB.

TypeIs также работает с переменными типов. Дополнительная информация содержится в PEP 742 (Сужение типов с помощью TypeIs).

Добавлена в версии 3.13.

typing.TypeGuard

Специальная конструкция типизации для маркирования пользовательских функций-предикатов типов.

Функции-предикаты типов — это пользовательские функции, которые возвращают истинность того, является ли их аргумент экземпляром конкретного типа. TypeGuard работает аналогично TypeIs, но имеет немного отличающиеся эффекты на поведение проверки типов (см. ниже).

Использование -> TypeGuard сообщает инструменту статической типизации, что для данной функции:

  1. Значение возврата является булевым.
  2. Если возвращаемое значение True, тип его аргумента — это тип внутри TypeGuard.

TypeGuard также работает с переменными типов. Дополнительная информация содержится в PEP 647.

Например:

def is_str_list(val: list[object]) -> TypeGuard[list[str]]:
    '''Determines whether all objects in the list are strings'''
    return all(isinstance(x, str) for x in val)

def func1(val: list[object]):
    if is_str_list(val):
        # Type of ``val`` is narrowed to ``list[str]``.
        print(" ".join(val))
    else:
        # Type of ``val`` remains as ``list[object]``.
        print("Not a list of strings!")

TypeIs и TypeGuard различаются следующим образом:

  • TypeIs требует, чтобы суженный тип был подтипом входного типа, в то время как TypeGuard — нет. Основная причина — позволить такие вещи, как сужение list[object] до list[str], даже если последний не является подтипом первого, поскольку list инвариантен.
  • Когда функция TypeGuard возвращает True, инструменты проверки типов сужают тип переменной ровно до типа TypeGuard. Когда функция TypeIs возвращает True, инструменты проверки типов могут вывести более точный тип, комбинируя ранее известный тип переменной с типом TypeIs. (Технически это называется пересекающимся типом).
  • Когда функция TypeGuard возвращает False, инструменты проверки типов не могут сузить тип переменной вообще. Когда функция TypeIs возвращает False, инструменты проверки типов могут сузить тип переменной, исключив тип TypeIs.

Добавлена в версии 3.10.

typing.Unpack

Оператор типизации для концептуальной маркировки объекта как распакованного.

Например, использование оператора распаковки * над кортежем переменной типа type variable tuple эквивалентно использованию Unpack для маркировки кортежа переменной типа как распакованного:

Ts = TypeVarTuple('Ts')
tup: tuple[*Ts]
# Effectively does:
tup: tuple[Unpack[Ts]]

Фактически, Unpack может использоваться взаимозаменяемо с * в контексте типов typing.TypeVarTuple и builtins.tuple. Вы можете увидеть Unpack явно используемым в более старых версиях Python, где * не могло использоваться в определённых местах:

# In older versions of Python, TypeVarTuple and Unpack
# are located in the `typing_extensions` backports package.
from typing_extensions import TypeVarTuple, Unpack

Ts = TypeVarTuple('Ts')
tup: tuple[*Ts]         # Syntax error on Python <= 3.10!
tup: tuple[Unpack[Ts]]  # Semantically equivalent, and backwards-compatible

Unpack также может использоваться вместе с typing.TypedDict для типизации **kwargs в сигнатуре функции:

from typing import TypedDict, Unpack

class Movie(TypedDict):
    name: str
    year: int

# This function expects two keyword arguments - `name` of type `str`
# and `year` of type `int`.
def foo(**kwargs: Unpack[Movie]): ...

См. PEP 692 для получения более подробной информации об использовании Unpack для **kwargs типизации.

Добавлена в версии 3.11.

Создание обобщённых типов и псевдонимов типов

Следующие классы не должны использоваться напрямую в качестве аннотаций. Их предназначение — служить строительными блоками для создания обобщённых типов и псевдонимов типов.

Эти объекты могут быть созданы с помощью специальной синтаксической конструкции (списки параметров типа и оператор type). Для совместимости с Python 3.11 и более ранними версиями они также могут быть созданы без специальной синтаксической конструкции, как описано ниже.

class typing.Generic

Абстрактный базовый класс для обобщённых типов.

Обобщённый тип обычно объявляется добавлением списка параметров типа после имени класса:

class Mapping[KT, VT]:
    def __getitem__(self, key: KT) -> VT:
        ...
        # Etc.

Такой класс неявно наследуется от Generic. Семантика этого синтаксиса на уровне выполнения обсуждается в Справочнике языка.

Затем этот класс можно использовать следующим образом:

def lookup_name[X, Y](mapping: Mapping[X, Y], key: X, default: Y) -> Y:
    try:
        return mapping[key]
    except KeyError:
        return default

Здесь скобки после имени функции указывают на обобщённую функцию.

Для обратной совместимости обобщённые классы также могут быть объявлены путём явного наследования от Generic. В этом случае параметры типа должны быть объявлены отдельно:

KT = TypeVar('KT')
VT = TypeVar('VT')

class Mapping(Generic[KT, VT]):
    def __getitem__(self, key: KT) -> VT:
        ...
        # Etc.
class typing.TypeVar(name, *constraints, bound=None, covariant=False, contravariant=False, infer_variance=False, default=typing.NoDefault)

Переменная типа.

Предпочтительный способ построения переменной типа — через специальный синтаксис для обобщённых функций, обобщённых классов и обобщённых псевдонимов типов:

class Sequence[T]:  # T is a TypeVar
    ...

Этот синтаксис также может быть использован для создания ограниченных и подчинённых переменных типа:

class StrSequence[S: str]:  # S is a TypeVar with a `str` upper bound;
    ...                     # we can say that S is "bounded by `str`"


class StrOrBytesSequence[A: (str, bytes)]:  # A is a TypeVar constrained to str or bytes
    ...

Однако, при необходимости, повторно используемые переменные типа также можно создать вручную, например так:

T = TypeVar('T')  # Can be anything
S = TypeVar('S', bound=str)  # Can be any subtype of str
A = TypeVar('A', str, bytes)  # Must be exactly str or bytes

Переменные типа в основном используются для статических проверочных систем типов. Они служат параметрами для обобщённых типов, а также для определений обобщённых функций и псевдонимов типов. См. Generic для получения дополнительной информации об обобщённых типах. Обобщённые функции работают следующим образом:

def repeat[T](x: T, n: int) -> Sequence[T]:
    """Return a list containing n references to x."""
    return [x]*n


def print_capitalized[S: str](x: S) -> S:
    """Print x capitalized, and return x."""
    print(x.capitalize())
    return x


def concatenate[A: (str, bytes)](x: A, y: A) -> A:
    """Add two strings or bytes objects together."""
    return x + y

Обратите внимание, что переменные типа могут быть ограниченными, подчинёнными или ни тем, ни другим, но не могут быть одновременно ограниченными и подчинёнными.

Вариативность переменных типа определяется системами проверки типов при создании через синтаксис параметров типа или при передаче infer_variance=True. Ручные переменные типа могут быть явно помечены как ковариантные или контравариантные, передавая covariant=True или contravariant=True. По умолчанию, вручную созданные переменные типа являются инвариантными. См. PEP 484 и PEP 695 для получения дополнительной информации.

Ограниченные переменные типа и подчинённые переменные типа имеют разные семантики в нескольких важных аспектах. Использование ограниченной переменной типа означает, что TypeVar будет решена с помощью наиболее конкретного возможного типа:

x = print_capitalized('a string')
reveal_type(x)  # revealed type is str

class StringSubclass(str):
    pass

y = print_capitalized(StringSubclass('another string'))
reveal_type(y)  # revealed type is StringSubclass

z = print_capitalized(45)  # error: int is not a subtype of str

Верхняя граница переменной типа может быть конкретным типом, абстрактным типом (ABC или Protocol), или даже объединением типов:

# Can be anything with an __abs__ method
def print_abs[T: SupportsAbs](arg: T) -> None:
    print("Absolute value:", abs(arg))

U = TypeVar('U', bound=str|bytes)  # Can be any subtype of the union str|bytes
V = TypeVar('V', bound=SupportsAbs)  # Can be anything with an __abs__ method

Однако, использование подчинённой переменной типа означает, что TypeVar может быть решена только как один из заданных ограничений:

a = concatenate('one', 'two')
reveal_type(a)  # revealed type is str

b = concatenate(StringSubclass('one'), StringSubclass('two'))
reveal_type(b)  # revealed type is str, despite StringSubclass being passed in

c = concatenate('one', b'two')  # error: type variable 'A' can be either str or bytes in a function call, but not both

При выполнении isinstance(x, T) будет поднято исключение TypeError.

__name__

Имя переменной типа.

__covariant__

Указывает, была ли переменная типа явно помечена как ковариативная.

__contravariant__

Указывает, была ли переменная типа явно помечена как контравариантная.

__infer_variance__

Указывает, должна ли система проверки типов выводить вариативность переменной типа.

Добавлена в версии 3.12.

__bound__

Верхняя граница переменной типа, если она задана.

Изменено в версии 3.12: Для переменных типа, созданных через синтаксис параметров типа, граница вычисляется только при обращении к атрибуту, а не при создании переменной типа (см. Ленивое вычисление).

__constraints__

Кортеж, содержащий ограничения переменной типа, если они заданы.

Изменено в версии 3.12: Для переменных типа, созданных через синтаксис параметров типа, ограничения вычисляются только при обращении к атрибуту, а не при создании переменной типа (см. Ленивое вычисление).

__default__

Значение по умолчанию переменной типа или typing.NoDefault, если значение по умолчанию не задано.

Добавлена в версии 3.13.

has_default()

Возвращает True, если переменная типа имеет значение по умолчанию, и False в противном случае. Это эквивалентно проверке того, что __default__ не является синглтоном typing.NoDefault, за исключением того, что это не принуждает к вычислению значения по умолчанию.

Добавлена в версии 3.13.

Изменено в версии 3.12: Переменные типа теперь могут быть объявлены с помощью синтаксиса параметра типа, представленного в PEP 695. Параметр infer_variance был добавлен.

Изменено в версии 3.13: Добавлена поддержка значений по умолчанию.

class typing.TypeVarTuple(name, *, default=typing.NoDefault)

Кортеж переменных типов. Специализированная форма переменной типа, которая позволяет использовать вариативные обобщения.

Кортежи переменных типов могут быть объявлены в списках параметров типа с помощью одного символа звездочки (*) перед именем:

def move_first_element_to_last[T, *Ts](tup: tuple[T, *Ts]) -> tuple[*Ts, T]:
    return (*tup[1:], tup[0])

Или, явно вызвав конструктор TypeVarTuple:

T = TypeVar("T")
Ts = TypeVarTuple("Ts")

def move_first_element_to_last(tup: tuple[T, *Ts]) -> tuple[*Ts, T]:
    return (*tup[1:], tup[0])

Обычная переменная типа позволяет параметризацию с одним типом. Кортеж переменных типов, в отличие от этого, позволяет параметризацию с любым количеством типов, действуя как любое количество переменных типа, упакованных в кортеж. Например:

# T is bound to int, Ts is bound to ()
# Return value is (1,), which has type tuple[int]
move_first_element_to_last(tup=(1,))

# T is bound to int, Ts is bound to (str,)
# Return value is ('spam', 1), which has type tuple[str, int]
move_first_element_to_last(tup=(1, 'spam'))

# T is bound to int, Ts is bound to (str, float)
# Return value is ('spam', 3.0, 1), which has type tuple[str, float, int]
move_first_element_to_last(tup=(1, 'spam', 3.0))

# This fails to type check (and fails at runtime)
# because tuple[()] is not compatible with tuple[T, *Ts]
# (at least one element is required)
move_first_element_to_last(tup=())

Обратите внимание на использование оператора распаковки * в tuple[T, *Ts]. Концептуально, вы можете представить Ts как кортеж переменных типа (T1, T2, ...). tuple[T, *Ts] затем станет tuple[T, *(T1, T2, ...)], что эквивалентно tuple[T, T1, T2, ...]. (Обратите внимание, что в более старых версиях Python это могло быть записано с использованием Unpack вместо, как Unpack[Ts].)

Кортежи переменных типов всегда должны быть распакованы. Это помогает отличить кортежи переменных типов от обычных переменных типов:

x: Ts          # Not valid
x: tuple[Ts]   # Not valid
x: tuple[*Ts]  # The correct way to do it

Кортежи переменных типов могут использоваться в тех же контекстах, что и обычные переменные типа. Например, в определениях классов, аргументах и типах возвращаемых значений:

class Array[*Shape]:
    def __getitem__(self, key: tuple[*Shape]) -> float: ...
    def __abs__(self) -> "Array[*Shape]": ...
    def get_shape(self) -> tuple[*Shape]: ...

Кортежи переменных типов могут быть успешно объединены с обычными переменными типов:

class Array[DType, *Shape]:  # This is fine
    pass

class Array2[*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

Однако обратите внимание, что в одном списке аргументов типа или параметров типа может появиться не более одного кортежа переменных типов:

x: tuple[*Ts, *Ts]            # Not valid
class Array[*Shape, *Shape]:  # Not valid
    pass

Наконец, распакованный кортеж переменных типа может использоваться в качестве аннотации типа для *args:

def call_soon[*Ts](
    callback: Callable[[*Ts], None],
    *args: *Ts
) -> None:
    ...
    callback(*args)

В отличие от нераспакованных аннотаций для *args - например, *args: int, которая бы указала, что все аргументы являются int - *args: *Ts позволяет обратиться к типам отдельных аргументов в *args. Здесь это позволяет нам гарантировать, что типы *args , передаваемые call_soon , соответствуют типам (позиционных) аргументов callback.

См. PEP 646 для получения дополнительной информации о кортежах переменных типов.

__name__

Имя кортежа переменных типов.

__default__

Значение по умолчанию кортежа переменных типов или typing.NoDefault, если оно отсутствует.

Добавлен в версии 3.13.

has_default()

Возвращает, имеет ли кортеж переменных типов значение по умолчанию. Это эквивалентно проверке, является ли __default__ не равным typing.NoDefault-объекту, за исключением того, что это не принуждает к вычислению значения по умолчанию, которое вычисляется лениво.

Добавлен в версии 3.13.

Добавлен в версии 3.11.

Изменено в версии 3.12: Кортежи переменных типов теперь могут быть объявлены с помощью синтаксиса параметра типа, представленного в PEP 695.

Изменено в версии 3.13: Добавлена поддержка значений по умолчанию.

class typing.ParamSpec(name, *, bound=None, covariant=False, contravariant=False, default=typing.NoDefault)

Переменная спецификации параметра. Специализированная версия переменных типов.

В списках параметров типов (в списках параметров типов) спецификации параметров можно объявлять с помощью двух звёздочек (**):

type IntFunc[**P] = Callable[P, int]

Для совместимости с Python 3.11 и более ранними версиями, объекты ParamSpec также можно создавать следующим образом:

P = ParamSpec('P')

Переменные спецификации параметров в основном предназначены для статических проверок типов. Они используются для передачи типов параметров одного вызываемого объекта другому вызываемому объекту — шаблон, часто встречающийся в высших порядковых функциях и декораторах. Они допустимы только при использовании в Concatenate, или в качестве первого аргумента Callable, или в качестве параметров для пользовательских обобщенных типов. Подробнее об обобщенных типах см. Generic.

Например, чтобы добавить базовый логгинг в функцию, можно создать декоратор add_logging для регистрации вызовов функций. Переменная спецификации параметра сообщает проверке типов, что вызываемые объекты, переданные в декоратор и новый вызываемый объект, возвращаемый им, имеют взаимозависимые параметры типов:

from collections.abc import Callable
import logging

def add_logging[T, **P](f: Callable[P, T]) -> Callable[P, T]:
    '''A type-safe decorator to add logging to a function.'''
    def inner(*args: P.args, **kwargs: P.kwargs) -> T:
        logging.info(f'{f.__name__} was called')
        return f(*args, **kwargs)
    return inner

@add_logging
def add_two(x: float, y: float) -> float:
    '''Add two numbers together.'''
    return x + y

Без ParamSpec, самый простой способ аннотации этого ранее был с использованием TypeVar с верхним ограничением Callable[..., Any]. Однако это создает две проблемы:

  1. Проверка типов не может проверить функцию inner, потому что *args и **kwargs должны быть типизированы как Any.
  2. cast() может потребоваться в теле декоратора add_logging при возвращении функции inner, или статической проверке типов необходимо сказать игнорировать return inner.
args
kwargs

Поскольку ParamSpec охватывает как позиционные, так и именованные параметры, P.args и P.kwargs могут использоваться для разделения ParamSpec на компоненты. P.args представляет собой кортеж позиционных параметров в данном вызове и должен использоваться только для аннотации *args. P.kwargs представляет собой отображение именованных параметров к их значениям в данном вызове и должно использоваться только для аннотации **kwargs. Оба атрибута требуют, чтобы аннотируемый параметр находился в области видимости. Во время выполнения, P.args и P.kwargs являются соответственно экземплярами ParamSpecArgs и ParamSpecKwargs.

__name__

Имя спецификации параметра.

__default__

Значение по умолчанию спецификации параметра или typing.NoDefault, если значение по умолчанию отсутствует.

Добавлена в версии 3.13.

has_default()

Возвращает, имеет ли спецификация параметра значение по умолчанию. Это эквивалентно проверке, не является ли __default__ экземпляром typing.NoDefault, за исключением того, что это не приводит к принудительной оценке лениво оцениваемого значения по умолчанию.

Добавлена в версии 3.13.

Переменные спецификации параметров, созданные с помощью covariant=True или contravariant=True, могут использоваться для объявления ковариативных или контравариантных обобщенных типов. Также принимается аргумент bound, подобно TypeVar. Однако фактическая семантика этих ключевых слов еще не определена.

Добавлена в версии 3.10.

Изменено в версии 3.12: Теперь спецификации параметров можно объявлять, используя синтаксис параметров типов параметров типов, введённый в PEP 695.

Изменено в версии 3.13: Добавлена поддержка значений по умолчанию.

Примечание

Только переменные спецификации параметров, определённые в глобальной области, могут быть сериализованы.

См. также

  • PEP 612 — Переменные спецификации параметров (PEP, в котором были введены ParamSpec и Concatenate)
  • Concatenate
  • Аннотация вызываемых объектов
typing.ParamSpecArgs
typing.ParamSpecKwargs

Атрибуты аргументов и именованных аргументов для ParamSpec. Атрибут P.args для ParamSpec является экземпляром ParamSpecArgs, а P.kwargs — экземпляром ParamSpecKwargs. Они предназначены для интроспекции во время выполнения и не имеют специального значения для статических проверок типов.

Вызов get_origin() для любого из этих объектов вернет исходный ParamSpec:

>>> from typing import ParamSpec, get_origin
>>> P = ParamSpec("P")
>>> get_origin(P.args) is P
True
>>> get_origin(P.kwargs) is P
True

Добавлена в версии 3.10.

class typing.TypeAliasType(name, value, *, type_params=())

Тип псевдонимов типов, созданных с помощью инструкции type.

Пример:

>>> type Alias = int
>>> type(Alias)
<class 'typing.TypeAliasType'>

Добавлена в версии 3.12.

__name__

Имя псевдонима типа:

>>> type Alias = int
>>> Alias.__name__
'Alias'
__module__

Модуль, в котором был определён псевдоним типа:

>>> type Alias = int
>>> Alias.__module__
'__main__'
__type_params__

Параметры типов псевдонима, или пустой кортеж, если псевдоним не является обобщённым:

>>> type ListOrSet[T] = list[T] | set[T]
>>> ListOrSet.__type_params__
(T,)
>>> type NotGeneric = int
>>> NotGeneric.__type_params__
()
__value__

Значение псевдонима типа. Оно лениво вычисляется, поэтому имена, используемые в определении псевдонима, не разрешаются до тех пор, пока не будет обращено к атрибуту __value__:

>>> type Mutually = Recursive
>>> type Recursive = Mutually
>>> Mutually
Mutually
>>> Recursive
Recursive
>>> Mutually.__value__
Recursive
>>> Recursive.__value__
Mutually

Другие специальные директивы

Эти функции и классы не следует использовать напрямую в качестве аннотаций. Их предназначение — быть строительными блоками для создания и объявления типов.

class typing.NamedTuple

Типизированная версия collections.namedtuple().

Использование:

class Employee(NamedTuple):
    name: str
    id: int

Это эквивалентно:

Employee = collections.namedtuple('Employee', ['name', 'id'])

Чтобы присвоить полю значение по умолчанию, можно задать его в теле класса:

class Employee(NamedTuple):
    name: str
    id: int = 3

employee = Employee('Guido')
assert employee.id == 3

Поля со значением по умолчанию должны следовать за полями без значения по умолчанию.

Получившийся класс имеет дополнительный атрибут __annotations__ , содержащий словарь, сопоставляющий имена полей с типами полей. (Имена полей находятся в атрибуте _fields, а значения по умолчанию — в атрибуте _field_defaults, оба из которых являются частью API namedtuple().)

NamedTuple подклассы также могут иметь строки документации и методы:

class Employee(NamedTuple):
    """Represents an employee."""
    name: str
    id: int = 3

    def __repr__(self) -> str:
        return f'<Employee {self.name}, id={self.id}>'

NamedTuple подклассы могут быть параметризованными:

class Group[T](NamedTuple):
    key: T
    group: list[T]

Совместимое с предыдущими версиями использование:

# For creating a generic NamedTuple on Python 3.11
T = TypeVar("T")

class Group(NamedTuple, Generic[T]):
    key: T
    group: list[T]

# A functional syntax is also supported
Employee = NamedTuple('Employee', [('name', str), ('id', int)])

Изменено в версии 3.6: Добавлена поддержка синтаксиса аннотаций переменных PEP 526.

Изменено в версии 3.6.1: Добавлена поддержка значений по умолчанию, методов и строк документации.

Изменено в версии 3.8: Атрибуты _field_types и __annotations__ теперь являются обычными словарями вместо экземпляров OrderedDict.

Изменено в версии 3.9: Удален атрибут _field_types в пользу более стандартного атрибута __annotations__ , содержащего ту же информацию.

Изменено в версии 3.11: Добавлена поддержка параметризованных namedtuple.

Устаревшее с версии 3.13, будет удалено в версии 3.15: Синтаксис ключевых аргументов для создания классов NamedTuple (NT = NamedTuple("NT", x=int)) устарел и будет запрещён в версии 3.15. Используйте синтаксис на основе классов или функциональный синтаксис.

Устаревшее с версии 3.13, будет удалено в версии 3.15: При использовании функционального синтаксиса для создания класса NamedTuple, пропуск значения для параметра «fields» (NT = NamedTuple("NT")) устарел. Передача None параметру «fields» (NT = NamedTuple("NT", None)) также устарела. Оба варианта будут запрещены в Python 3.15. Чтобы создать NamedTuple класс с 0 полями, используйте class NT(NamedTuple): pass или NT = NamedTuple("NT", []).

class typing.NewType(name, tp)

Вспомогательный класс для создания типов различных типов с низкой стоимостью.

А NewType считается типом различного типа, проверкой типов. Однако при выполнении вызов NewType возвращает аргумент без изменений.

Использование:

UserId = NewType('UserId', int)  # Declare the NewType "UserId"
first_user = UserId(1)  # "UserId" returns the argument unchanged at runtime
__module__

Модуль, в котором определён новый тип.

__name__

Имя нового типа.

__supertype__

Тип, на котором основан новый тип.

Добавлен в версии 3.5.2.

Изменено в версии 3.10: NewType теперь является классом, а не функцией.

class typing.Protocol(Generic)

Базовый класс для протокольных классов.

Протокольные классы определяются так:

class Proto(Protocol):
    def meth(self) -> int:
        ...

Эти классы в основном используются с проверками статического типа, которые распознают структурный подтип (статический duck-типинг), например:

class C:
    def meth(self) -> int:
        return 0

def func(x: Proto) -> int:
    return x.meth()

func(C())  # Passes static type check

Дополнительные сведения см. в PEP 544. Протокольные классы, помеченные runtime_checkable() (описанные ниже), действуют как простые протоколы в режиме выполнения, которые проверяют только наличие заданных атрибутов, игнорируя их сигнатуры типов.

Протокольные классы могут быть параметризованными, например:

class GenProto[T](Protocol):
    def meth(self) -> T:
        ...

В коде, который должен быть совместим с Python 3.11 или более ранними версиями, обобщённые протоколы можно записать следующим образом:

T = TypeVar("T")

class GenProto(Protocol[T]):
    def meth(self) -> T:
        ...

Добавлен в версии 3.8.

@typing.runtime_checkable

Пометить протокольный класс как протокол в режиме выполнения.

Такой протокол может использоваться с isinstance() и issubclass(). Это вызывает TypeError при применении к классу, не являющемуся протоколом. Это позволяет выполнить простую структурную проверку, очень похожую на «одногорючие» решения в collections.abc, такие как Iterable. Например:

@runtime_checkable
class Closable(Protocol):
    def close(self): ...

assert isinstance(open('/some/file'), Closable)

@runtime_checkable
class Named(Protocol):
    name: str

import threading
assert isinstance(threading.Thread(name='Bob'), Named)

Примечание

runtime_checkable() будет проверять только наличие необходимых методов или атрибутов, а не их сигнатуры типов или типы. Например, ssl.SSLObject — это класс, поэтому он проходит проверку issubclass() по отношению к Callable. Однако метод ssl.SSLObject.__init__ существует только для повышения TypeError с более информативным сообщением, поэтому сделать невозможным вызов (создание экземпляра) ssl.SSLObject.

Примечание

Проверка isinstance() по отношению к протоколу, поддерживаемому в режиме выполнения, может быть неожиданно медленной по сравнению с проверкой isinstance() по отношению к классу, не являющемуся протоколом. В производительно-чувствительном коде следует использовать альтернативные выражения, такие как вызовы hasattr() для структурных проверок.

Добавлен в версии 3.8.

Изменено в версии 3.12: Внутренняя реализация isinstance() проверок на предмет протоколов, поддерживаемых в режиме выполнения, теперь использует inspect.getattr_static() для поиска атрибутов (ранее использовалась hasattr()). В результате некоторые объекты, которые ранее считались экземплярами протокола, поддерживаемого в режиме выполнения, могут больше не считаться экземплярами этого протокола в Python 3.12 и выше, и наоборот. Большинство пользователей вряд ли будут затронуты этим изменением.

Изменено в версии 3.12: Члены протокола, поддерживаемого в режиме выполнения, теперь считаются «замороженными» в режиме выполнения, как только класс был создан. Подмена атрибутов протокола, поддерживаемого в режиме выполнения, по-прежнему будет работать, но не повлияет на проверки isinstance(), сравнивающие объекты с протоколом. См. “Что нового в Python 3.12” для получения дополнительных сведений.

class typing.TypedDict(dict)

Специальная конструкция для добавления подсказок типов к словарю. Во время выполнения это обычный dict.

TypedDict объявляет тип словаря, который ожидает, что все его экземпляры будут иметь определенный набор ключей, где каждый ключ связан со значением согласованного типа. Это ожидание не проверяется во время выполнения, а только проверяется средствами проверки типов. Использование:

class Point2D(TypedDict):
    x: int
    y: int
    label: str

a: Point2D = {'x': 1, 'y': 2, 'label': 'good'}  # OK
b: Point2D = {'z': 3, 'label': 'bad'}           # Fails type check

assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first')

Альтернативный способ создания TypedDict — использование синтаксиса вызова функции. Второй аргумент должен быть литералом dict:

Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str})

Этот функциональный синтаксис позволяет определять ключи, которые не являются допустимыми идентификаторами, например, потому что они являются ключевыми словами или содержат дефисы:

# raises SyntaxError
class Point2D(TypedDict):
    in: int  # 'in' is a keyword
    x-y: int  # name with hyphens

# OK, functional syntax
Point2D = TypedDict('Point2D', {'in': int, 'x-y': int})

По умолчанию все ключи должны присутствовать в TypedDict. Возможна пометка отдельных ключей как необязательных с помощью NotRequired:

class Point2D(TypedDict):
    x: int
    y: int
    label: NotRequired[str]

# Alternative syntax
Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': NotRequired[str]})

Это означает, что Point2D TypedDict может иметь ключ label пропущенным.

Также можно по умолчанию отметить все ключи как необязательные, указав значение False:

class Point2D(TypedDict, total=False):
    x: int
    y: int

# Alternative syntax
Point2D = TypedDict('Point2D', {'x': int, 'y': int}, total=False)

Это означает, что Point2D TypedDict может иметь любые ключи пропущенными. Проверяющий типов должен поддерживать только литеральный False или True в качестве значения аргумента total. True — это значение по умолчанию, и делает все элементы, определённые в теле класса, обязательными.

Отдельные ключи total=False TypedDict могут быть помечены как обязательные с помощью Required:

class Point2D(TypedDict, total=False):
    x: Required[int]
    y: Required[int]
    label: str

# Alternative syntax
Point2D = TypedDict('Point2D', {
    'x': Required[int],
    'y': Required[int],
    'label': str
}, total=False)

Тип TypedDict может наследоваться от одного или нескольких других типов TypedDict с использованием синтаксиса на основе класса. Пример:

class Point3D(Point2D):
    z: int

Point3D содержит три элемента: x, y и z. Он эквивалентен этому определению:

class Point3D(TypedDict):
    x: int
    y: int
    z: int

TypedDict не может наследоваться от не-TypedDict класса, за исключением Generic. Например:

class X(TypedDict):
    x: int

class Y(TypedDict):
    y: int

class Z(object): pass  # A non-TypedDict class

class XY(X, Y): pass  # OK

class XZ(X, Z): pass  # raises TypeError

TypedDict может быть обобщённым:

class Group[T](TypedDict):
    key: T
    group: list[T]

Чтобы создать обобщённый TypedDict совместимый с Python 3.11 или ниже, явно унаследуйте от Generic:

T = TypeVar("T")

class Group(TypedDict, Generic[T]):
    key: T
    group: list[T]

TypedDict можно проинспектировать через словари аннотаций (см. Рекомендации по применению аннотаций для получения дополнительной информации об аннотациях).

__total__, __required_keys__ и __optional_keys__.
__total__

Point2D.__total__ возвращает значение аргумента total . Пример:

>>> from typing import TypedDict
>>> class Point2D(TypedDict): pass
>>> Point2D.__total__
True
>>> class Point2D(TypedDict, total=False): pass
>>> Point2D.__total__
False
>>> class Point3D(Point2D): pass
>>> Point3D.__total__
True

Этот атрибут отражает только значение аргумента total текущего TypedDict класса, а не то, является ли класс семантически полным. Например, TypedDict с __total__ равным True может иметь ключи, помеченные как NotRequired, или он может унаследоваться от другого TypedDict с total=False. Поэтому для интроспекции лучше использовать __required_keys__ и __optional_keys__.

__required_keys__

Добавлен в версии 3.9.

__optional_keys__

Point2D.__required_keys__ и Point2D.__optional_keys__ возвращают объекты frozenset, содержащие обязательные и необязательные ключи соответственно.

Ключи, помеченные как Required, всегда будут появляться в __required_keys__, а ключи, помеченные как NotRequired, всегда будут появляться в __optional_keys__.

Для обратной совместимости с Python 3.10 и ниже также возможно использовать наследование, чтобы объявить как обязательные, так и необязательные ключи в одном TypedDict. Это делается путём объявления TypedDict с одним значением для аргумента total и затем наследованием от него в другом TypedDict с другим значением для total:

>>> class Point2D(TypedDict, total=False):
...     x: int
...     y: int
...
>>> class Point3D(Point2D):
...     z: int
...
>>> Point3D.__required_keys__ == frozenset({'z'})
True
>>> Point3D.__optional_keys__ == frozenset({'x', 'y'})
True

Добавлен в версии 3.9.

Примечание

Если используется from __future__ import annotations или если аннотации заданы в виде строк, аннотации не оцениваются при определении TypedDict. Следовательно, динамическая интроспекция, на которой __required_keys__ и __optional_keys__ полагаются, может работать неправильно, и значения атрибутов могут быть неверными.

Поддержка ReadOnly отражается в следующих атрибутах:

__readonly_keys__

frozenset, содержащий имена всех только для чтения ключей. Ключи являются только для чтения, если они содержат квалификатор ReadOnly.

Добавлен в версии 3.13.

__mutable_keys__

frozenset, содержащий имена всех изменяемых ключей. Ключи изменяемые, если они не содержат квалификатор ReadOnly.

Добавлен в версии 3.13.

См. PEP 589 для получения дополнительных примеров и подробных правил использования TypedDict.

Добавлен в версии 3.8.

Изменено в версии 3.11: Добавлена поддержка маркировки отдельных ключей как Required или NotRequired. См. PEP 655.

Изменено в версии 3.11: Добавлена поддержка обобщённых TypedDict.

Изменено в версии 3.13: Убрана поддержка метода ключевых аргументов для создания TypedDict.

Изменено в версии 3.13: Добавлена поддержка квалификатора ReadOnly.

Устарело начиная с версии 3.13, будет удалено в версии 3.15: При использовании функционального синтаксиса для создания класса TypedDict, отсутствие значения для параметра ‘fields’ (TD = TypedDict("TD")) устарело. Передача None параметру ‘fields’ (TD = TypedDict("TD", None)) также устарела. Оба будут запрещены в Python 3.15. Чтобы создать класс TypedDict с 0 полями, используйте class TD(TypedDict): pass или TD = TypedDict("TD", {}).

Протоколы

Следующие протоколы предоставляются модулем typing. Все они декорированы @runtime_checkable.

class typing.SupportsAbs

ABC с одним абстрактным методом __abs__ , который является ковариантным по своему возвращаемому типу.

class typing.SupportsBytes

ABC с одним абстрактным методом __bytes__.

class typing.SupportsComplex

ABC с одним абстрактным методом __complex__.

class typing.SupportsFloat

ABC с одним абстрактным методом __float__.

class typing.SupportsIndex

ABC с одним абстрактным методом __index__.

Добавлен в версии 3.8.

class typing.SupportsInt

ABC с одним абстрактным методом __int__.

class typing.SupportsRound

ABC с одним абстрактным методом __round__ , который является ковариантным по своему возвращаемому типу.

ABC для работы с IO

class typing.IO
class typing.TextIO
class typing.BinaryIO

Обобщенный тип IO[AnyStr] и его подклассы TextIO(IO[str]) и BinaryIO(IO[bytes]) представляют типы потоков ввода-вывода, таких как возвращаемые функцией open().

Функции и декораторы

typing.cast(typ, val)

Преобразование значения к типу.

Возвращает значение без изменений. Для анализатора типов это сигнализирует, что возвращаемое значение имеет указанный тип, но во время выполнения проверок не выполняется (мы хотим, чтобы это было максимально быстро).

typing.assert_type(val, typ, /)

Запрос статического анализатора типов для подтверждения, что val имеет выведенный тип typ.

Во время выполнения это ничего не делает: возвращает первый аргумент без изменений без проверок или побочных эффектов, независимо от фактического типа аргумента.

Когда статический анализатор типов встречает вызов assert_type(), он выдает ошибку, если значение не соответствует указанному типу:

def greet(name: str) -> None:
    assert_type(name, str)  # OK, inferred type of `name` is `str`
    assert_type(name, int)  # type checker error

Эта функция полезна для обеспечения соответствия понимания анализатора типов намерениям разработчика:

def complex_function(arg: object):
    # Do some complex type-narrowing logic,
    # after which we hope the inferred type will be `int`
    ...
    # Test whether the type checker correctly understands our function
    assert_type(arg, int)

Добавлена в версии 3.11.

typing.assert_never(arg, /)

Запрос статического анализатора типов для подтверждения, что строка кода недостижима.

Пример:

def int_or_str(arg: int | str) -> None:
    match arg:
        case int():
            print("It's an int")
        case str():
            print("It's a str")
        case _ as unreachable:
            assert_never(unreachable)

Здесь аннотации позволяют анализатору типов сделать вывод, что последний случай никогда не выполнится, потому что arg является либо int, либо str, и оба варианта покрыты предыдущими случаями.

Если анализатор типов обнаружит, что вызов assert_never() достижим, он выведет ошибку. Например, если аннотация типа для arg была вместо этого int | str | float, анализатор типов выведет ошибку, указав, что unreachable имеет тип float. Для того, чтобы вызов assert_never прошел проверку типов, выведенный тип переданного аргумента должен быть типом "ничего", Never, и ничем другим.

Во время выполнения это вызывает исключение при вызове.

См. также

Проверка недостижимого кода и полноты содержит больше информации о проверке полноты при статическом типизировании.

Добавлена в версии 3.11.

typing.reveal_type(obj, /)

Запрос статического анализатора типов для отображения выведенного типа выражения.

Когда статический анализатор типов встречает вызов этой функции, он выводит диагностику с выведенным типом аргумента. Например:

x: int = 1
reveal_type(x)  # Revealed type is "builtins.int"

Это может быть полезно, когда вы хотите отладить то, как ваш анализатор типов обрабатывает конкречный фрагмент кода.

Во время выполнения эта функция выводит тип аргумента во время выполнения в sys.stderr и возвращает аргумент без изменений (разрешая использование вызова в выражении):

x = reveal_type(1)  # prints "Runtime type is int"
print(x)  # prints "1"

Обратите внимание, что тип во время выполнения может отличаться от (более или менее специфичен, чем) тип, статически выведенный анализатором типов.

Большинство анализаторов типов поддерживают reveal_type() в любом месте, даже если имя не импортировано из typing. Однако импорт имени из typing, позволяет вашему коду работать без ошибок во время выполнения и яснее отражает намерение.

Добавлена в версии 3.11.

@typing.dataclass_transform(*, eq_default=True, order_default=False, kw_only_default=False, frozen_default=False, field_specifiers=(), **kwargs)

Декоратор для маркировки объекта как предоставляющего поведение, подобное dataclass.

dataclass_transform может быть использован для декорирования класса, метакласса или функции, которая сама по себе является декоратором. Наличие @dataclass_transform() сообщает статическому анализатору типов, что декорируемый объект выполняет операции «волшебства» во время выполнения, преобразующие класс аналогично @dataclasses.dataclass.

Пример использования с функцией-декоратором:

@dataclass_transform()
def create_model[T](cls: type[T]) -> type[T]:
    ...
    return cls

@create_model
class CustomerModel:
    id: int
    name: str

На базовом классе:

@dataclass_transform()
class ModelBase: ...

class CustomerModel(ModelBase):
    id: int
    name: str

На метаклассе:

@dataclass_transform()
class ModelMeta(type): ...

class ModelBase(metaclass=ModelMeta): ...

class CustomerModel(ModelBase):
    id: int
    name: str

Классы CustomerModel выше будут обрабатываться анализаторами типов аналогично классам, созданным с помощью @dataclasses.dataclass. Например, анализаторы типов будут предполагать, что эти классы имеют __init__ методы, которые принимают id и name.

Декорированный класс, метакласс или функция могут принимать следующие логические аргументы, которые анализаторы типов будут предполагать имеющими тот же эффект, что и у декоратора @dataclasses.dataclass: init, eq, order, unsafe_hash, frozen, match_args, kw_only, и slots. Значение этих аргументов (True или False) должно быть статически вычислимо.

Аргументы декоратора dataclass_transform могут использоваться для настройки поведения по умолчанию декорированного класса, метакласса или функции:

Параметры:
  • eq_default (bool) – Указывает, предполагается ли, что параметр eq имеет значение True или False при его опущении вызывающим кодом. По умолчанию True.
  • order_default (bool) – Указывает, предполагается ли, что параметр order имеет значение True или False при его опущении вызывающим кодом. По умолчанию False.
  • kw_only_default (bool) – Указывает, предполагается ли, что параметр kw_only имеет значение True или False при его опущении вызывающим кодом. По умолчанию False.
  • frozen_default (bool) –

    Указывает, предполагается ли, что параметр frozen имеет значение True или False при его опущении вызывающим кодом. По умолчанию False.

    Добавлена в версии 3.12.

  • field_specifiers (tuple[Callable[..., Any], ...]) – Указывает статический список поддерживаемых классов или функций, описывающих поля, подобно dataclasses.field(). По умолчанию ().
  • **kwargs (Any) – Принимаются произвольные другие ключевые аргументы для возможных будущих расширений.

Анализаторы типов распознают следующие необязательные параметры в спецификаторах полей:

Распознанные параметры для спецификаторов полей

Имя параметра

Описание

init

Указывает, следует ли включать поле в синтезированный метод __init__. Если не указано, init по умолчанию True.

default

Предоставляет значение по умолчанию для поля.

default_factory

Предоставляет обратный вызов во время выполнения, возвращающий значение по умолчанию для поля. Если ни default, ни default_factory не указаны, поле предполагается без значения по умолчанию и должно быть предоставлено значение при создании экземпляра класса.

factory

Псевдоним для параметра default_factory в спецификаторах полей.

kw_only

Указывает, следует ли помечать поле как только для ключевых аргументов. Если True, поле будет только для ключевых аргументов. Если False, оно не будет только для ключевых аргументов. Если не указано, используется значение параметра kw_only в объекте, декорированном dataclass_transform, или, если он не указан, значение kw_only_default в dataclass_transform.

alias

Предоставляет альтернативное имя для поля. Это альтернативное имя используется в синтезированном методе __init__.

Во время выполнения этот декоратор записывает свои аргументы в атрибуте __dataclass_transform__ декорируемого объекта. Он не имеет других эффектов во время выполнения.

См. PEP 681 для получения дополнительной информации.

Добавлена в версии 3.11.

@typing.overload

Декоратор для создания перегруженных функций и методов.

Декоратор @overload позволяет описывать функции и методы, которые поддерживают несколько различных комбинаций типов аргументов. Последовательность определений, помеченных декоратором @overload, должна следовать за ровно одним определением, не помеченным декоратором @overload (для той же функции/метода).

Определения, помеченные декоратором @overload, предназначены только для проверки типов, так как они будут перезаписаны определением, не помеченным декоратором @overload. Определение, не помеченное декоратором @overload, в свою очередь, будет использоваться во время выполнения, но должно игнорироваться проверяющим типы. При вызове функции, помеченной декоратором @overload, во время выполнения будет возбуждено исключение NotImplementedError.

Пример перегрузки, которая предоставляет более точный тип, чем можно выразить с помощью объединения или переменной типа:

@overload
def process(response: None) -> None:
    ...
@overload
def process(response: int) -> tuple[int, str]:
    ...
@overload
def process(response: bytes) -> str:
    ...
def process(response):
    ...  # actual implementation goes here

См. PEP 484 для получения более подробной информации и сравнения с другими семантиками типов.

Изменено в версии 3.11: Теперь перегруженные функции можно инспектировать во время выполнения с помощью get_overloads().

typing.get_overloads(func)

Возвращает последовательность определений, помеченных декоратором @overload, для func.

func — это объект функции для реализации перегруженной функции. Например, в документации к @overload приведено определение process, функция get_overloads(process) вернет последовательность из трёх объектов функций для трёх определённых перегрузок. Если вызов производится для функции без перегрузок, get_overloads() возвращает пустую последовательность.

get_overloads() может использоваться для инспектирования перегруженной функции во время выполнения.

Добавлен в версии 3.11.

typing.clear_overloads()

Очищает все зарегистрированные перегрузки в внутренней базе данных.

Это может использоваться для освобождения памяти, занимаемой базой данных.

Добавлен в версии 3.11.

@typing.final

Декоратор для указания финальных методов и финальных классов.

Пометка метода декоратором @final указывает проверяющему типу, что метод не может быть переопределён в подклассе. Пометка класса декоратором @final указывает, что он не может быть наследован.

Например:

class Base:
    @final
    def done(self) -> None:
        ...
class Sub(Base):
    def done(self) -> None:  # Error reported by type checker
        ...

@final
class Leaf:
    ...
class Other(Leaf):  # Error reported by type checker
    ...

Проверки этих свойств во время выполнения нет. См. PEP 591 для получения более подробной информации.

Добавлен в версии 3.8.

Изменено в версии 3.11: Декоратор теперь попытается установить атрибут __final__ со значением True для помеченного объекта. Таким образом, проверка типа if getattr(obj, "__final__", False) может использоваться во время выполнения для определения, был ли объект obj помечен как финальный. Если помеченный объект не поддерживает установку атрибутов, декоратор возвращает объект без изменений, не вызывая исключения.

@typing.no_type_check

Декоратор, указывающий, что аннотации не являются подсказками типов.

Он работает как декоратор класса или функции. Для класса он применяется рекурсивно ко всем методам и классам, определённым в этом классе (но не к методам, определённым в его суперклассах или подклассах). Проверяющие типы игнорируют все аннотации в функции или классе с этим декоратором.

@no_type_check изменяет помеченный объект на месте.

@typing.no_type_check_decorator

Декоратор, предоставляющий другому декоратору эффект no_type_check().

Он оборачивает декоратор в нечто, что оборачивает помеченную функцию в no_type_check().

Устарело начиная с версии 3.13, будет удалено в версии 3.15: Ни один проверяющий тип никогда не добавлял поддержки @no_type_check_decorator. Поэтому он устарел и будет удалён в Python 3.15.

@typing.override

Декоратор, указывающий, что метод в подклассе предназначен для переопределения метода или атрибута в суперклассе.

Проверяющие типы должны генерировать ошибку, если метод, помеченный декоратором @override, фактически не переопределяет ничего. Это помогает предотвратить ошибки, которые могут возникнуть при изменении базового класса без соответствующих изменений в дочернем классе.

Например:

class Base:
    def log_status(self) -> None:
        ...

class Sub(Base):
    @override
    def log_status(self) -> None:  # Okay: overrides Base.log_status
        ...

    @override
    def done(self) -> None:  # Error reported by type checker
        ...

Проверки этого свойства во время выполнения нет.

Декоратор попытается установить атрибут __override__ со значением True для помеченного объекта. Таким образом, проверка if getattr(obj, "__override__", False) может быть использована во время выполнения для определения, был ли объект obj помечен как переопределение. Если помеченный объект не поддерживает установку атрибутов, декоратор возвращает объект без изменений, не вызывая исключение.

См. PEP 698 для получения более подробной информации.

Добавлен в версии 3.12.

@typing.type_check_only

Декоратор для пометки класса или функции как недоступных во время выполнения.

Этот декоратор сам по себе недоступен во время выполнения. Он предназначен в основном для пометки классов, определённых в файлах типов, если реализация возвращает экземпляр частного класса:

@type_check_only
class Response:  # private or not available at runtime
    code: int
    def get_header(self, name: str) -> str: ...

def fetch_response() -> Response: ...

Обратите внимание, что возвращение экземпляров частных классов не рекомендуется. Обычно предпочтительнее сделать такие классы общедоступными.

Инструменты интроспекции

typing.get_type_hints(obj, globalns=None, localns=None, include_extras=False)

Возвращает словарь, содержащий подсказки типов для функции, метода, модуля или объекта класса.

Это часто то же самое, что и obj.__annotations__, но эта функция вносит следующие изменения в словарь аннотаций:

  • Ссылаясь на будущее, закодированные как строковые литералы или объекты ForwardRef, обрабатываются путем их вычисления в пространствах имен globalns, localns и (применимо) в пространстве имен параметра типа объекта obj. Если globalns или localns не заданы, соответствующие словари пространств имен выводятся из obj.
  • None заменяется на types.NoneType.
  • Если к obj применён @no_type_check, возвращается пустой словарь.
  • Если obj является классом C, функция возвращает словарь, который объединяет аннотации из базовых классов C с аннотациями, заданными непосредственно на C. Это делается путем обхода C.__mro__ и итеративного объединения словарей __annotations__. Аннотации классов, появляющихся ранее в порядке разрешения методов, всегда имеют приоритет над аннотациями классов, появляющихся позже в порядке разрешения методов.
  • Функция рекурсивно заменяет все вхождения Annotated[T, ...] на T, если include_extras не установлено в True (см. Annotated для получения дополнительной информации).

См. также inspect.get_annotations(), функцию более низкого уровня, которая возвращает аннотации более непосредственно.

Примечание

Если какие-либо ссылки на будущее в аннотациях obj не разрешимы или не являются допустимым Python-кодом, эта функция вызовет исключение, такое как NameError. Например, это может произойти с импортированными псевдонимами типов, которые включают ссылки на будущее, или с именами, импортированными под if TYPE_CHECKING.

Изменено в версии 3.9: Добавлен параметр include_extras как часть PEP 593. См. документацию по Annotated для получения дополнительной информации.

Изменено в версии 3.11: Ранее Optional[t] добавлялся для аннотаций функций и методов, если значение по умолчанию равнялось None. Теперь аннотация возвращается без изменений.

typing.get_origin(tp)

Получить незамещенную версию типа: для объекта типа typing в форме X[Y, Z, ...] вернуть X.

Если X является псевдонимом модуля typing для встроенного или collections класса, он будет нормализован до исходного класса. Если X является экземпляром ParamSpecArgs или ParamSpecKwargs, вернуть базовый ParamSpec. Вернуть None для неподдерживаемых объектов.

Примеры:

assert get_origin(str) is None
assert get_origin(Dict[str, int]) is dict
assert get_origin(Union[int, str]) is Union
assert get_origin(Annotated[str, "metadata"]) is Annotated
P = ParamSpec('P')
assert get_origin(P.args) is P
assert get_origin(P.kwargs) is P

Добавлен в версии 3.8.

typing.get_args(tp)

Получить аргументы типов со всеми выполненными подстановками: для объекта типа typing в форме X[Y, Z, ...] вернуть (Y, Z, ...).

Если X является объединением или Literal, содержащимся в другом типе универсального типа, порядок (Y, Z, ...) может отличаться от порядка исходных аргументов [Y, Z, ...] из-за кэширования типов. Вернуть () для неподдерживаемых объектов.

Примеры:

assert get_args(int) == ()
assert get_args(Dict[int, str]) == (int, str)
assert get_args(Union[int, str]) == (int, str)

Добавлен в версии 3.8.

typing.get_protocol_members(tp)

Возвращает набор членов, определенных в Protocol.

>>> from typing import Protocol, get_protocol_members
>>> class P(Protocol):
...     def a(self) -> str: ...
...     b: int
>>> get_protocol_members(P) == frozenset({'a', 'b'})
True

Вызвать TypeError для аргументов, которые не являются протоколами.

Добавлен в версии 3.13.

typing.is_protocol(tp)

Определить, является ли тип Protocol.

Например:

class P(Protocol):
    def a(self) -> str: ...
    b: int

is_protocol(P)    # => True
is_protocol(int)  # => False

Добавлен в версии 3.13.

typing.is_typeddict(tp)

Проверить, является ли тип TypedDict.

Например:

class Film(TypedDict):
    title: str
    year: int

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)

Добавлен в версии 3.10.

class typing.ForwardRef

Класс, используемый для внутреннего представления типа строк со ссылками на будущее.

Например, List["SomeClass"] неявно преобразуется в List[ForwardRef("SomeClass")]. ForwardRef не должен создаваться пользователем, но может использоваться инструментами интроспекции.

Примечание

PEP 585 универсальные типы, такие как list["SomeClass"] не будут неявно преобразованы в list[ForwardRef("SomeClass")] и, следовательно, не будут автоматически разрешены до list[SomeClass].

Добавлен в версии 3.7.4.

typing.NoDefault

Объект-маяк, используемый для указания того, что параметр типа не имеет значения по умолчанию. Например:

>>> T = TypeVar("T")
>>> T.__default__ is typing.NoDefault
True
>>> S = TypeVar("S", default=None)
>>> S.__default__ is None
True

Добавлен в версии 3.13.

Константа

typing.TYPE_CHECKING

Специальная константа, которая предполагается True сторонними статическими проверяющими типов. Она False во время выполнения.

Использование:

if TYPE_CHECKING:
    import expensive_mod

def fun(arg: 'expensive_mod.SomeType') -> None:
    local_var: expensive_mod.AnotherType = other_fun()

Первая аннотация типа должна быть заключена в кавычки, делая её «ссылкой на будущее», чтобы скрыть ссылку expensive_mod от интерпретатора во время выполнения. Аннотации типов для локальных переменных не вычисляются, поэтому вторую аннотацию заключать в кавычки не нужно.

Примечание

Если from __future__ import annotations используется, аннотации не вычисляются во время определения функции. Вместо этого они хранятся как строки в __annotations__. Это делает ненужным использование кавычек вокруг аннотации (см. PEP 563).

Добавлен в версии 3.5.2.

Устаревшие псевдонимы

Этот модуль определяет несколько устаревших псевдонимов для существующих классов стандартной библиотеки. Изначально они были включены в модуль `typing` для поддержки параметризации этих обобщенных классов с помощью []. Однако, псевдонимы стали избыточными в Python 3.9, когда соответствующие существующие классы были дополнены поддержкой [] (см. PEP 585).

Избыточные типы устарели начиная с Python 3.9. Однако, хотя псевдонимы могут быть удалены в какой-то момент, их удаление в настоящее время не планируется. Поэтому интерпретатор в настоящее время не выдает предупреждений об устаревании для этих псевдонимов.

Если в какой-то момент будет принято решение удалить эти устаревшие псевдонимы, предупреждение об устаревании будет выдаваться интерпретатором как минимум за два выпуска до удаления. Псевдонимы гарантированно останутся в модуле `typing` без предупреждений об устаревании как минимум до Python 3.14.

Рекомендуется, чтобы средства проверки типов отмечали использование устаревших типов, если проверяемая программа ориентирована на минимальную версию Python 3.9 или выше.

Псевдонимы для встроенных типов

class typing.Dict(dict, MutableMapping[KT, VT])

Устаревший псевдоним для dict.

Обратите внимание, что для аннотирования аргументов предпочтительнее использовать абстрактный тип коллекции, такой как Mapping, а не dict или typing.Dict.

Устарел начиная с версии 3.9: builtins.dict теперь поддерживает индексацию ([]). См. PEP 585 и Тип обобщенного псевдонима.

class typing.List(list, MutableSequence[T])

Устаревший псевдоним для list.

Обратите внимание, что для аннотирования аргументов предпочтительнее использовать абстрактный тип коллекции, такой как Sequence или Iterable, а не list или typing.List.

Устарел начиная с версии 3.9: builtins.list теперь поддерживает индексацию ([]). См. PEP 585 и Тип обобщенного псевдонима.

class typing.Set(set, MutableSet[T])

Устаревший псевдоним для builtins.set.

Обратите внимание, что для аннотирования аргументов предпочтительнее использовать абстрактный тип коллекции, такой как collections.abc.Set, а не set или typing.Set.

Устарел начиная с версии 3.9: builtins.set теперь поддерживает индексацию ([]). См. PEP 585 и Тип обобщенного псевдонима.

class typing.FrozenSet(frozenset, AbstractSet[T_co])

Устаревший псевдоним для builtins.frozenset.

Устарел начиная с версии 3.9: builtins.frozenset теперь поддерживает индексацию ([]). См. PEP 585 и Тип обобщенного псевдонима.

typing.Tuple

Устаревший псевдоним для tuple.

tuple и Tuple имеют специальную обработку в системе типов; см. Аннотирование кортежей для получения дополнительной информации.

Устарел начиная с версии 3.9: builtins.tuple теперь поддерживает индексацию ([]). См. PEP 585 и Тип обобщенного псевдонима.

class typing.Type(Generic[CT_co])

Устаревший псевдоним для type.

См. Тип объектов класса для получения подробной информации об использовании type или typing.Type в аннотациях типов.

Добавлен в версии 3.5.2.

Устарел начиная с версии 3.9: builtins.type теперь поддерживает индексацию ([]). См. PEP 585 и Тип обобщенного псевдонима.

Псевдонимы типов в collections

class typing.DefaultDict(collections.defaultdict, MutableMapping[KT, VT])

Устаревший псевдоним для collections.defaultdict.

Добавлен в версии 3.5.2.

Устарело с версии 3.9: collections.defaultdict теперь поддерживает индексирование ([]). См. PEP 585 и Тип обобщённого псевдонима.

class typing.OrderedDict(collections.OrderedDict, MutableMapping[KT, VT])

Устаревший псевдоним для collections.OrderedDict.

Добавлен в версии 3.7.2.

Устарело с версии 3.9: collections.OrderedDict теперь поддерживает индексирование ([]). См. PEP 585 и Тип обобщённого псевдонима.

class typing.ChainMap(collections.ChainMap, MutableMapping[KT, VT])

Устаревший псевдоним для collections.ChainMap.

Добавлен в версии 3.6.1.

Устарело с версии 3.9: collections.ChainMap теперь поддерживает индексирование ([]). См. PEP 585 и Тип обобщённого псевдонима.

class typing.Counter(collections.Counter, Dict[T, int])

Устаревший псевдоним для collections.Counter.

Добавлен в версии 3.6.1.

Устарело с версии 3.9: collections.Counter теперь поддерживает индексирование ([]). См. PEP 585 и Тип обобщённого псевдонима.

class typing.Deque(deque, MutableSequence[T])

Устаревший псевдоним для collections.deque.

Добавлен в версии 3.6.1.

Устарело с версии 3.9: collections.deque теперь поддерживает индексирование ([]). См. PEP 585 и Тип обобщённого псевдонима.

Псевдонимы других конкретных типов

class typing.Pattern
class typing.Match

Устаревшие псевдонимы, соответствующие типам возвращаемых значений от re.compile() и re.match().

Эти типы (и соответствующие функции) обобщены по AnyStr. Pattern может быть специализирован как Pattern[str] или Pattern[bytes]; Match может быть специализирован как Match[str] или Match[bytes].

Устарело с версии 3.9: Классы Pattern и Match из re теперь поддерживают []. См. PEP 585 и Тип обобщённого псевдонима.

class typing.Text

Устаревший псевдоним для str.

Text предоставляется для обеспечения совместимости с кодом Python 2: в Python 2, Text является псевдонимом для unicode.

Используйте Text для указания того, что значение должно содержать строку Unicode таким образом, чтобы оно было совместимо как с Python 2, так и с Python 3:

def add_unicode_checkmark(text: Text) -> Text:
    return text + u' \u2713'

Добавлен в версии 3.5.2.

Устарело с версии 3.11: Python 2 больше не поддерживается, и большинство проверяющих типов также больше не поддерживают проверку типов кода Python 2. Удаление псевдонима в настоящее время не планируется, но пользователям рекомендуется использовать str вместо Text.

Псевдонимы контейнерных ABC в collections.abc

class typing.AbstractSet(Collection[T_co])

Устаревший псевдоним для collections.abc.Set.

Устарело начиная с версии 3.9: collections.abc.Set теперь поддерживает индексирование ([]). См. PEP 585 и Тип универсального псевдонима.

class typing.ByteString(Sequence[int])

Этот тип представляет типы bytes, bytearray и memoryview последовательностей байтов.

Устарело начиная с версии 3.9, будет удалено в версии 3.14: Предпочтительнее использовать collections.abc.Buffer или объединение, например, bytes | bytearray | memoryview.

class typing.Collection(Sized, Iterable[T_co], Container[T_co])

Устаревший псевдоним для collections.abc.Collection.

Добавлен в версии 3.6.

Устарело начиная с версии 3.9: collections.abc.Collection теперь поддерживает индексирование ([]). См. PEP 585 и Тип универсального псевдонима.

class typing.Container(Generic[T_co])

Устаревший псевдоним для collections.abc.Container.

Устарело начиная с версии 3.9: collections.abc.Container теперь поддерживает индексирование ([]). См. PEP 585 и Тип универсального псевдонима.

class typing.ItemsView(MappingView, AbstractSet[tuple[KT_co, VT_co]])

Устаревший псевдоним для collections.abc.ItemsView.

Устарело начиная с версии 3.9: collections.abc.ItemsView теперь поддерживает индексирование ([]). См. PEP 585 и Тип универсального псевдонима.

class typing.KeysView(MappingView, AbstractSet[KT_co])

Устаревший псевдоним для collections.abc.KeysView.

Устарело начиная с версии 3.9: collections.abc.KeysView теперь поддерживает индексирование ([]). См. PEP 585 и Тип универсального псевдонима.

class typing.Mapping(Collection[KT], Generic[KT, VT_co])

Устаревший псевдоним для collections.abc.Mapping.

Устарело начиная с версии 3.9: collections.abc.Mapping теперь поддерживает индексирование ([]). См. PEP 585 и Тип универсального псевдонима.

class typing.MappingView(Sized)

Устаревший псевдоним для collections.abc.MappingView.

Устарело начиная с версии 3.9: collections.abc.MappingView теперь поддерживает индексирование ([]). См. PEP 585 и Тип универсального псевдонима.

class typing.MutableMapping(Mapping[KT, VT])

Устаревший псевдоним для collections.abc.MutableMapping.

Устарело начиная с версии 3.9: collections.abc.MutableMapping теперь поддерживает индексирование ([]). См. PEP 585 и Тип универсального псевдонима.

class typing.MutableSequence(Sequence[T])

Устаревший псевдоним для collections.abc.MutableSequence.

Устарело начиная с версии 3.9: collections.abc.MutableSequence теперь поддерживает индексирование ([]). См. PEP 585 и Тип универсального псевдонима.

class typing.MutableSet(AbstractSet[T])

Устаревший псевдоним для collections.abc.MutableSet.

Устарело начиная с версии 3.9: collections.abc.MutableSet теперь поддерживает индексирование ([]). См. PEP 585 и Тип универсального псевдонима.

class typing.Sequence(Reversible[T_co], Collection[T_co])

Устаревший псевдоним для collections.abc.Sequence.

Устарело начиная с версии 3.9: collections.abc.Sequence теперь поддерживает индексирование ([]). См. PEP 585 и Тип универсального псевдонима.

END_OF_DOCUMENT_MARKER
class typing.ValuesView(MappingView, Collection[_VT_co])

Устаревшее псевдоним для collections.abc.ValuesView.

Устарело начиная с версии 3.9: collections.abc.ValuesView теперь поддерживает индексацию ([]). См. PEP 585 и Тип обобщённого псевдонима.

Псевдонимы асинхронных ABC в collections.abc

class typing.Coroutine(Awaitable[ReturnType], Generic[YieldType, SendType, ReturnType])

Устаревшее псевдоним для collections.abc.Coroutine.

См. Аннотирование генераторов и корутин для получения подробной информации об использовании collections.abc.Coroutine и typing.Coroutine в аннотациях типов.

Добавлен в версии 3.5.3.

Устарело начиная с версии 3.9: collections.abc.Coroutine теперь поддерживает индексацию ([]). См. PEP 585 и Тип обобщённого псевдонима.

class typing.AsyncGenerator(AsyncIterator[YieldType], Generic[YieldType, SendType])

Устаревшее псевдоним для collections.abc.AsyncGenerator.

См. Аннотирование генераторов и корутин для получения подробной информации об использовании collections.abc.AsyncGenerator и typing.AsyncGenerator в аннотациях типов.

Добавлен в версии 3.6.1.

Устарело начиная с версии 3.9: collections.abc.AsyncGenerator теперь поддерживает индексацию ([]). См. PEP 585 и Тип обобщённого псевдонима.

Изменено в версии 3.13: Параметр SendType теперь имеет значение по умолчанию.

class typing.AsyncIterable(Generic[T_co])

Устаревшее псевдоним для collections.abc.AsyncIterable.

Добавлен в версии 3.5.2.

Устарело начиная с версии 3.9: collections.abc.AsyncIterable теперь поддерживает индексацию ([]). См. PEP 585 и Тип обобщённого псевдонима.

class typing.AsyncIterator(AsyncIterable[T_co])

Устаревшее псевдоним для collections.abc.AsyncIterator.

Добавлен в версии 3.5.2.

Устарело начиная с версии 3.9: collections.abc.AsyncIterator теперь поддерживает индексацию ([]). См. PEP 585 и Тип обобщённого псевдонима.

class typing.Awaitable(Generic[T_co])

Устаревшее псевдоним для collections.abc.Awaitable.

Добавлен в версии 3.5.2.

Устарело начиная с версии 3.9: collections.abc.Awaitable теперь поддерживает индексацию ([]). См. PEP 585 и Тип обобщённого псевдонима.

Псевдонимы других ABC в collections.abc

class typing.Iterable(Generic[T_co])

Устаревший псевдоним для collections.abc.Iterable.

Устарело начиная с версии 3.9: collections.abc.Iterable теперь поддерживает индексирование ([]). См. PEP 585 и Тип обобщенного псевдонима.

class typing.Iterator(Iterable[T_co])

Устаревший псевдоним для collections.abc.Iterator.

Устарело начиная с версии 3.9: collections.abc.Iterator теперь поддерживает индексирование ([]). См. PEP 585 и Тип обобщенного псевдонима.

typing.Callable

Устаревший псевдоним для collections.abc.Callable.

Подробности использования collections.abc.Callable и typing.Callable в аннотациях типов см. в разделе Аннотирование вызываемых объектов.

Устарело начиная с версии 3.9: collections.abc.Callable теперь поддерживает индексирование ([]). См. PEP 585 и Тип обобщенного псевдонима.

Изменено в версии 3.10: Callable теперь поддерживает ParamSpec и Concatenate. Дополнительные сведения см. в PEP 612.

class typing.Generator(Iterator[YieldType], Generic[YieldType, SendType, ReturnType])

Устаревший псевдоним для collections.abc.Generator.

Подробности использования collections.abc.Generator и typing.Generator в аннотациях типов см. в разделе Аннотирование генераторов и корутин.

Устарело начиная с версии 3.9: collections.abc.Generator теперь поддерживает индексирование ([]). См. PEP 585 и Тип обобщенного псевдонима.

Изменено в версии 3.13: Были добавлены значения по умолчанию для типов send и return.

class typing.Hashable

Устаревший псевдоним для collections.abc.Hashable.

Устарело начиная с версии 3.12: Используйте collections.abc.Hashable напрямую.

class typing.Reversible(Iterable[T_co])

Устаревший псевдоним для collections.abc.Reversible.

Устарело начиная с версии 3.9: collections.abc.Reversible теперь поддерживает индексирование ([]). См. PEP 585 и Тип обобщенного псевдонима.

class typing.Sized

Устаревший псевдоним для collections.abc.Sized.

Устарело начиная с версии 3.12: Используйте collections.abc.Sized напрямую.

Псевдонимы ABC из contextlib

class typing.ContextManager(Generic[T_co, ExitT_co])

Устаревший псевдоним для contextlib.AbstractContextManager.

Первый параметр типа, T_co, представляет тип, возвращаемый методом __enter__(). Необязательный второй параметр типа, ExitT_co, по умолчанию bool | None, представляет тип, возвращаемый методом __exit__().

Добавлен в версии 3.5.4.

Устарело начиная с версии 3.9: contextlib.AbstractContextManager теперь поддерживает индексирование ([]). См. PEP 585 и Тип обобщенного псевдонима.

Изменено в версии 3.13: Добавлен необязательный второй параметр типа, ExitT_co.

class typing.AsyncContextManager(Generic[T_co, AExitT_co])

Устаревший псевдоним для contextlib.AbstractAsyncContextManager.

Первый параметр типа, T_co, представляет тип, возвращаемый методом __aenter__(). Необязательный второй параметр типа, AExitT_co, по умолчанию bool | None, представляет тип, возвращаемый методом __aexit__().

Добавлен в версии 3.6.2.

Устарело начиная с версии 3.9: contextlib.AbstractAsyncContextManager теперь поддерживает индексирование ([]). См. PEP 585 и Тип обобщенного псевдонима.

Изменено в версии 3.13: Добавлен необязательный второй параметр типа, AExitT_co.

График устаревания основных функций

Определенные функции в typing устарели и могут быть удалены в будущей версии Python. В следующей таблице обобщены основные устаревания для вашего удобства. Данные могут быть изменены, и не все устаревания перечислены.

Функция

Устарело в

Прогнозируемое удаление

PEP/задача

typing версии стандартных коллекций

3.9

Не определено (см. Устаревшие алиасы для получения дополнительной информации)

PEP 585

typing.ByteString

3.9

3.14

gh-91896

typing.Text

3.11

Не определено

gh-92332

typing.Hashable и typing.Sized

3.12

Не определено

gh-94309

typing.TypeAlias

3.12

Не определено

PEP 695

@typing.no_type_check_decorator

3.13

3.15

gh-106309

typing.AnyStr

3.13

3.18

gh-105578

© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/typing.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API