Документация Python неофициальный перевод
Содержание страницы

typing – Поддержка аннотаций типовtyping – Support for type hints

Добавлено в версии 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.

См. также

Шпаргалка по typing

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

Раздел справочника по системе типов из документации mypy

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

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

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

Спецификация системы типов PythonSpecification for the Python Type System

Каноническая, актуальная спецификация системы типов Python находится по адресу Specification for the Python type system.

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

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

type Vector = list[float]

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

# проходит проверку типов; список чисел с плавающей точкой считается 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:
    ...

# Статическая проверка типов будет считать предыдущую сигнатуру типа как
# полностью эквивалентную этой.
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:
    ...

# проходит проверку типов
user_a = get_user_name(UserId(42351))

# не проходит проверку типов; int не является UserId
user_b = get_user_name(-1)

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

# 'output' имеет тип 'int', а не '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)

# Завершается ошибкой во время выполнения и не проходит проверку типов
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.

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

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

Например:

from collections.abc import Callable, Awaitable

def feeder(get_next_item: Callable[[], str]) -> None:
    ...  # Тело

def async_query(on_success: Callable[[int], None],
                on_error: Callable[[int, Exception], None]) -> None:
    ...  # Тело

async def on_update(value: str) -> None:
    ...  # Тело

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

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

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

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

x: Callable[..., str]
x = str     # ОК
x = concat  # Тоже ОК

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)  # ОК
batch_proc([], bad_cb)   # Ошибка! Аргумент 2 имеет несовместимый тип из-за
                         # другого имени и вида в колбэке

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

Changed in version 3.10: Callable now supports ParamSpec and Concatenate. See PEP 612 for more details.

См. также

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

Обобщённые типыGenerics

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

from collections.abc import Mapping, Sequence

class Employee: ...

# Sequence[Employee] означает, что все элементы последовательности
# должны быть экземплярами "Employee".
# Mapping[str, str] означает, что все ключи и все значения в отображении
# должны быть строками.
def notify_by_email(employees: Sequence[Employee],
                    overrides: Mapping[str, str]) -> None: ...

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

from collections.abc import Sequence

def first[T](l: Sequence[T]) -> T:  # Функция универсальна (обобщена) по TypeVar "T"
    return l[0]

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

from collections.abc import Sequence
from typing import TypeVar

U = TypeVar('U')                  # Объявить переменную типа "U"

def second(l: Sequence[U]) -> U:  # Функция универсальна (обобщена) по TypeVar "U"
    return l[1]

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

Аннотация кортежейAnnotating tuples

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

from collections.abc import Mapping

# Проверка типов выведет, что все элементы в ``x`` должны иметь тип int.
x: list[int] = []

# Ошибка проверки типов: ``list`` принимает только один аргумент типа:
y: list[int, str] = [1, 'foo']

# Проверка типов выведет, что все ключи в ``z`` должны быть строками,
# а все значения в ``z`` должны быть строками или int.
z: Mapping[str, str | int] = {}

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

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

# OK: ``x`` присваивается кортежу длины 1, единственный элемент которого – int.
x: tuple[int] = (5,)

# OK: ``y`` присваивается кортежу длины 2;
# элемент 1 – int, элемент 2 – str.
y: tuple[int, str] = (5, "foo")

# Ошибка: аннотация типа указывает на кортеж длины 1,
# но ``z`` был присвоен кортеж длины 3.
z: tuple[int] = (1, 2, 3)

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

x: tuple[int, ...] = (1, 2)
# Эти переприсваивания OK: ``tuple[int, ...]`` указывает, что x может быть любой длины.
x = (1, 2, 3)
x = ()
# Это переприсваивание – ошибка: все элементы в ``x`` должны быть int.
x = ("foo", "bar")

# ``y`` может быть присвоен только пустому кортежу.
y: tuple[()] = ()

z: tuple = ("foo", "bar")
# Эти переприсваивания OK: простой ``tuple`` эквивалентен ``tuple[Any, ...]``.
z = (1, 2, 3)
z = ()

Тип объектов классовThe type of class objects

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

a = 3         # Имеет тип ``int``.
b = int       # Имеет тип ``type[int]``.
c = type(a)   # Также имеет тип ``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)      # ОК
make_new_user(ProUser)   # Также OK: ``type[ProUser]`` – подтип ``type[User]``.
make_new_user(TeamUser)  # По-прежнему допустимо.
make_new_user(User())    # Ошибка: ожидался ``type[User]``, но получен ``User``.
make_new_user(int)       # Ошибка: ``type[int]`` не является подтипом ``type[User]``.

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

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

new_non_team_user(BasicUser)  # ОК
new_non_team_user(ProUser)    # ОК
new_non_team_user(TeamUser)   # Ошибка: ``type[TeamUser]`` не является подтипом
                              # ``type[BasicUser | ProUser]``.
new_non_team_user(User)       # Тоже ошибка.

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

Аннотация генераторов и корутинAnnotating generators and coroutines

Генератор можно аннотировать с помощью обобщённого типа 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]  # Некоторая корутина, определённая в другом месте.
x = c.send('hi')                   # Выведенный тип 'x' – list[str].
async def bar() -> None:
    y = await c                    # Выведенный тип 'y' – int.

Пользовательские обобщённые типыUser-defined generic types

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

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): # То же, что и Iterable[Any].
    ...

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

from collections.abc import Iterable

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

# Тип возвращаемого значения здесь такой же, как 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: # То же, что и 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 – это TypeVar; P – это 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 являются хешируемыми и сравнимыми на равенство.

Тип AnyThe Any type

Особым видом типа является Any. Статический анализатор типов будет считать любой тип присваиваемым Any, а Any – присваиваемым любому типу.

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

from typing import Any

a: Any = None
a = []          # ОК
a = 2           # ОК

s: str = ''
s = a           # ОК

def foo(item: Any) -> int:
    # Проходит проверку типов; 'item' может быть любого типа,
    # и этот тип может иметь метод 'bar'
    item.bar()
    ...

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

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

def legacy_parser(text):
    ...
    return data

# Статический проверщик типов будет рассматривать вышеприведенное
# как имеющее ту же сигнатуру, что и:
def legacy_parser(text: Any) -> Any:
    ...
    return data

Такое поведение позволяет использовать Any в качестве запасного выхода, когда нужно смешивать динамически и статически типизированный код.

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

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

def hash_a(item: object) -> int:
    # Не проходит проверку типов; у объекта нет метода 'magic'.
    item.magic()
    ...

def hash_b(item: Any) -> int:
    # Проходит проверку типов
    item.magic()
    ...

# Проходит проверку типов, так как int и str являются подклассами object
hash_a(42)
hash_a("foo")

# Проходит проверку типов, так как Any может быть присвоен любому типу
hash_b(42)
hash_b("foo")

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

Номинальная и структурная типизацияNominal vs structural subtyping

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

Ранее это требование также применялось к абстрактным базовым классам, таким как Iterable. Проблема такого подхода в том, что класс должен быть явно помечен для их поддержки, что непитонично и не похоже на то, что обычно делается в идиоматическом динамически типизированном коде 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:  # Примечание: базовые классы отсутствуют
    ...
    def __len__(self) -> int: ...
    def __iter__(self) -> Iterator[int]: ...

def collect(items: Iterable[int]) -> int: ...
result = collect(Bucket())  # Проходит проверку типов

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

Содержимое модуляModule contents

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

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

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

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

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, результат имеет тип 'str'
concat(b"foo", b"bar")  # OK, результат имеет тип 'bytes'
concat("foo", b"bar")   # Ошибка, нельзя смешивать str и bytes

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

# Неверное использование AnyStr:
# Переменная типа используется только один раз в сигнатуре функции,
# поэтому не может быть «решена» проверщиком типов
def greet_bad(cond: bool) -> AnyStr:
    return "hi there!" if cond else b"greetings!"

# Лучший способ аннотировать эту функцию:
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")  # ОК
    run_query(literal_string)  # ОК
    run_query("SELECT * FROM " + literal_string)  # ОК
    run_query(arbitrary_string)  # ошибка проверки типов
    run_query(  # ошибка проверки типов
        f"SELECT * FROM students WHERE name = {arbitrary_string}"
    )

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

Подробнее см. PEP 675.

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

typing.Never
typing.NoReturn

Never и NoReturn представляют нижний тип, тип, не имеющий элементов.

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

from typing import Never  # или NoReturn

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

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

from typing import Never  # или NoReturn

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

def int_or_str(arg: int | str) -> None:
    never_call_me(arg)  # ошибка проверки типов
    match arg:
        case int():
            print("It's an int")
        case str():
            print("It's a str")
        case _:
            never_call_me(arg)  # OK, аргумент имеет тип Never (или 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())  # Раскрытый тип – "Foo"
reveal_type(SubclassOfFoo().return_self())  # Раскрытый тип – "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 здесь была бы некорректной аннотацией возврата,
    # так как возвращаемый объект всегда является экземпляром Eggs,
    # даже в подклассах.
    def returns_eggs(self) -> "Eggs":
        return Eggs()

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

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

typing.TypeAlias

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

Например:

from typing import TypeAlias

Factors: TypeAlias = list[int]

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

from typing import Generic, TypeAlias, TypeVar

T = TypeVar("T")

# "Box" ещё не существует,
# поэтому для прямой ссылки на Python <3.12 приходится использовать кавычки.
# Использование ``TypeAlias`` сообщает тайпчекеру, что это объявление псевдонима типа,
# а не присваивание переменной строкового значения.
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.

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

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

class typing.Union

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

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

  • Аргументы должны быть типами, и их должно быть как минимум один.

  • Объединения объединений разворачиваются, например:

    Union[Union[int, str], float] == Union[int, str, float]
    

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

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

    Union[int] == int  # Конструктор на самом деле возвращает 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. См. выражения типов объединений.

Изменено в версии 3.14: types.UnionType теперь является псевдонимом для Union, и оба Union[int, str] и int | str создают экземпляры одного и того же класса. Чтобы проверить, является ли объект Union во время выполнения, используйте isinstance(obj, Union). Для совместимости с более ранними версиями Python используйте get_origin(obj) is typing.Union or get_origin(obj) is types.UnionType.

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 и при создании экземпляров пользовательских обобщённых классов с параметрами ParamSpec. Последний параметр Concatenate должен быть ParamSpec или многоточие (...).

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

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

# Используйте эту блокировку, чтобы гарантировать, что только один поток выполняет функцию
# в любой момент времени.
my_lock = Lock()

def with_lock[**P, R](f: Callable[Concatenate[Lock, P], R]) -> Callable[P, R]:
    '''Типобезопасный декоратор, предоставляющий блокировку.'''
    def inner(*args: P.args, **kwargs: P.kwargs) -> R:
        # Передайте блокировку в качестве первого аргумента.
        return f(my_lock, *args, **kwargs)
    return inner

@with_lock
def sum_threadsafe(lock: Lock, numbers: list[float]) -> float:
    '''Складывайте список чисел потокобезопасным способом.'''
    with lock:
        return sum(numbers)

# Нам не нужно передавать блокировку вручную благодаря декоратору.
sum_threadsafe([1.1, 2.2, 3.3])

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

См. также

typing.Literal

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

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

Например:

def validate_simple(data: Any) -> Literal[True]:  # всегда возвращает True
    ...

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

open_helper('/some/path', 'r')      # Проходит проверку типов
open_helper('/other/path', 'typo')  # Ошибка в тайпчекере

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

Дополнительные сведения:

  • Аргументы должны быть литеральными значениями, и их должно быть хотя бы одно.

  • Вложенные типы Literal уплощаются, например:

    assert Literal[Literal[1, 2], 3] == Literal[1, 2, 3]
    

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

    type A = Literal[1, 2]
    assert Literal[A, 3] != Literal[1, 2, 3]
    
  • Повторяющиеся аргументы пропускаются, например:

    assert Literal[1, 2, 1] == Literal[1, 2]
    
  • При сравнении литералов порядок аргументов игнорируется, например:

    assert Literal[1, 2] == Literal[2, 1]
    
  • Нельзя наследовать или создавать экземпляр Literal.

  • Нельзя записать Literal[X][Y].

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

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

typing.ClassVar

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

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

class Starship:
    stats: ClassVar[dict[str, int]] = {} # переменная класса
    damage: int = 10                     # переменная экземпляра

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

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

enterprise_d = Starship(3000)
enterprise_d.stats = {} # Ошибка: установка переменной класса на экземпляре
Starship.stats = {}     # Это корректно.

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

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

typing.Final

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

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

Например:

MAX_SIZE: Final = 9000
MAX_SIZE += 1  # Ошибка, выдаваемая проверщиком типов

class Connection:
    TIMEOUT: Final[int] = 10

class FastConnector(Connection):
    TIMEOUT = 1  # Ошибка, выдаваемая проверщиком типов

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

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

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

typing.Required

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

В основном это полезно для total=False TypedDict. Подробнее см. TypedDict и PEP 655.

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

typing.NotRequired

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

Подробнее см. TypedDict и PEP 655.

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

typing.ReadOnly

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

Например:

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

def mutate_movie(m: Movie) -> None:
   m["year"] = 1999  # разрешено
   m["title"] = "The Matrix"  # ошибка проверки типов

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

Подробнее см. 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

a1 = Annotated[int, ValueRange(3, 10), ctype("char")]
a2 = Annotated[int, ctype("char"), ValueRange(3, 10)]

assert a1 != a2  # Порядок важен

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

Вложенные типы Annotated уплощаются. Порядок элементов метаданных начинается с самой внутренней аннотации:

assert Annotated[Annotated[int, ValueRange(3, 10)], ctype("char")] == Annotated[
    int, ValueRange(3, 10), ctype("char")
]

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

type From3To10[T] = Annotated[T, ValueRange(3, 10)]
assert Annotated[From3To10[int], 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)]

# При использовании в аннотации типа тайпчекер будет обрабатывать "V" так же, как
# ``Annotated[list[tuple[int, int]], MaxLen(10)]``:
type V = Vec[int]

Annotated нельзя использовать с распакованным TypeVarTuple:

type Variadic[*Ts] = Annotated[*Ts, Ann1] = 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.TypeForm

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

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

При использовании в выражении типа TypeForm описывает множество объектов формы типа. Он принимает единственный аргумент типа, который должен быть корректным выражением типа. TypeForm[T] описывает множество всех объектов формы типа, которые представляют тип T или типы, присваиваемые T.

TypeForm(obj) просто возвращает obj без изменений. Это полезно для явной пометки значения как формы типа для статических анализаторов типов.

Пример:

from typing import Any, TypeForm

def cast[T](typ: TypeForm[T], value: Any) -> T: ...

reveal_type(cast(int, "x"))  # Обнаруженный тип – "int"

Подробнее см. PEP 747.

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

typing.TypeIs

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

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

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

def is_str(val: str | float):
    # Предикат типа "isinstance"
    if isinstance(val, str):
        # Тип ``val`` сужается до ``str``
        ...
    else:
        # Иначе тип ``val`` сужается до ``float``.
        ...

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

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

  1. Возвращаемое значение – boolean.

  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):
        # Тип ``arg`` сужается до пересечения
        # ``Parent`` и ``Child``, что эквивалентно
        # ``Child``.
        assert_type(arg, Child)
    else:
        # Тип ``arg`` сужается, исключая ``Parent``,
        # так что остаётся только ``Unrelated``.
        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

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

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

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

  1. Возвращаемое значение – boolean.

  2. Если возвращаемое значение – True, то тип аргумента – это тип внутри TypeGuard.

TypeGuard также работает с переменными типа. См. PEP 647 для подробностей.

Например:

def is_str_list(val: list[object]) -> TypeGuard[list[str]]:
    '''Определяет, все ли объекты в списке являются строками'''
    return all(isinstance(x, str) for x in val)

def func1(val: list[object]):
    if is_str_list(val):
        # Тип ``val`` сужается до ``list[str]``.
        print(" ".join(val))
    else:
        # Тип ``val`` остаётся как ``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

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

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

Ts = TypeVarTuple('Ts')
tup: tuple[*Ts]
# Фактически делает:
tup: tuple[Unpack[Ts]]

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

# В старых версиях Python TypeVarTuple и Unpack
# находятся в пакете обратной совместимости `typing_extensions`.
from typing_extensions import TypeVarTuple, Unpack

Ts = TypeVarTuple('Ts')
tup: tuple[*Ts]         # Синтаксическая ошибка на Python <= 3.10!
tup: tuple[Unpack[Ts]]  # Семантически эквивалентно и обратно совместимо

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

from typing import TypedDict, Unpack

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

# Эта функция ожидает два именованных аргумента: `name` типа `str`
# и `year` типа `int`.
def foo(**kwargs: Unpack[Movie]): ...

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

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

Построение обобщённых типов и псевдонимов типовBuilding generic types and type aliases

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

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

class typing.Generic

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

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

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

Такой класс неявно наследуется от 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:
        ...
        # И т.д.
class typing.TypeVar(name, *constraints, bound=None, covariant=False, contravariant=False, infer_variance=False, default=typing.NoDefault)

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

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

class Sequence[T]:  # T – это TypeVar
    ...

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

class StrSequence[S: str]:  # S – это TypeVar с верхней границей `str`;
    ...                     # можно сказать, что S "ограничен `str`"


class StrOrBytesSequence[A: (str, bytes)]:  # A – это TypeVar, ограниченный str или bytes
    ...

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

T = TypeVar('T')  # Может быть чем угодно
S = TypeVar('S', bound=str)  # Может быть любым подтипом str
A = TypeVar('A', str, bytes)  # Должно быть ровно str или bytes

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

def repeat[T](x: T, n: int) -> Sequence[T]:
    """Возвращает список, содержащий n ссылок на x."""
    return [x]*n


def print_capitalized[S: str](x: S) -> S:
    """Печатает x с заглавной буквы и возвращает x."""
    print(x.capitalize())
    return x


def concatenate[A: (str, bytes)](x: A, y: A) -> A:
    """Складывает две строки или два объекта bytes."""
    return x + y

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

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

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

x = print_capitalized('a string')
reveal_type(x)  # выявленный тип – str

class StringSubclass(str):
    pass

y = print_capitalized(StringSubclass('another string'))
reveal_type(y)  # раскрытый тип – StringSubclass

z = print_capitalized(45)  # ошибка: int не является подтипом str

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

# Может быть чем угодно с методом __abs__
def print_abs[T: SupportsAbs](arg: T) -> None:
    print("Absolute value:", abs(arg))

U = TypeVar('U', bound=str|bytes)  # Может быть любым подтипом объединения str|bytes
V = TypeVar('V', bound=SupportsAbs)  # Может быть чем угодно с методом __abs__

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

a = concatenate('one', 'two')
reveal_type(a)  # выявленный тип – str

b = concatenate(StringSubclass('one'), StringSubclass('two'))
reveal_type(b)  # выявленный тип – str, несмотря на то что передан StringSubclass

c = concatenate('one', b'two')  # ошибка: типовая переменная 'A' может быть либо str, либо bytes в вызове функции, но не обоими одновременно

Во время выполнения isinstance(x, T) вызовет TypeError.

__name__

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

__covariant__

Является ли переменная типа явно помеченной как ковариантная.

__contravariant__

Является ли переменная типа явно помеченной как контравариантная.

__infer_variance__

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

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

__bound__

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

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

evaluate_bound()

Функция evaluate, соответствующая атрибуту __bound__. При прямом вызове этот метод поддерживает только формат VALUE, что эквивалентно прямому обращению к атрибуту __bound__, но объект метода можно передать в annotationlib.call_evaluate_function() для вычисления значения в другом формате.

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

__constraints__

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

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

evaluate_constraints()

Функция evaluate, соответствующая атрибуту __constraints__. При прямом вызове этот метод поддерживает только формат VALUE, что эквивалентно прямому обращению к атрибуту __constraints__, но объект метода можно передать в annotationlib.call_evaluate_function() для вычисления значения в другом формате.

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

__default__

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

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

evaluate_default()

Функция evaluate, соответствующая атрибуту __default__. При прямом вызове этот метод поддерживает только формат VALUE, что эквивалентно прямому обращению к атрибуту __default__, но объект метода можно передать в annotationlib.call_evaluate_function() для вычисления значения в другом формате.

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

has_default()

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

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

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

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

class typing.TypeVarTuple(name, *, bound=None, covariant=False, contravariant=False, infer_variance=False, 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 привязан к int, Ts привязан к ()
# Возвращаемое значение – (1,), тип которого tuple[int]
move_first_element_to_last(tup=(1,))

# T привязан к int, Ts привязан к (str,)
# Возвращаемое значение – ('spam', 1), тип которого tuple[str, int]
move_first_element_to_last(tup=(1, 'spam'))

# T привязан к int, Ts привязан к (str, float)
# Возвращаемое значение – ('spam', 3.0, 1), тип которого tuple[str, float, int]
move_first_element_to_last(tup=(1, 'spam', 3.0))

# Это не проходит проверку типов (и завершается ошибкой во время выполнения)
# потому что tuple[()] несовместим с tuple[T, *Ts]
# (требуется хотя бы один элемент)
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          # Недействительно
x: tuple[Ts]   # Недействительно
x: tuple[*Ts]  # Правильный способ сделать это

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

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]:  # Это нормально
    pass

class Array2[*Shape, DType]:  # Это тоже нормально
    pass

class Height: ...
class Width: ...

float_array_1d: Array[float, Height] = Array()     # Совершенно нормально
int_array_2d: Array[int, Height, Width] = Array()  # Да, тоже нормально

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

x: tuple[*Ts, *Ts]            # Недействительно
class Array[*Shape, *Shape]:  # Недействительно
    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__

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

__covariant__

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

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

__contravariant__

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

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

__infer_variance__

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

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

__default__

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

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

evaluate_default()

Функция evaluate, соответствующая атрибуту __default__. При прямом вызове этот метод поддерживает только формат VALUE, что эквивалентно прямому обращению к атрибуту __default__, но объект метода можно передать в annotationlib.call_evaluate_function() для вычисления значения в другом формате.

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

has_default()

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

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

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

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

Changed in version 3.12: Type variable tuples can now be declared using the type parameter syntax introduced by PEP 695.

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

Изменено в версии 3.15: Добавлена поддержка параметров bound, covariant, contravariant и infer_variance.

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

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

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

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

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

P = ParamSpec('P')

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

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

from collections.abc import Callable
import logging

def add_logging[T, **P](f: Callable[P, T]) -> Callable[P, T]:
    '''Типобезопасный декоратор для добавления логирования в функцию.'''
    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:
    '''Складывает два числа.'''
    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__

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

__covariant__

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

__contravariant__

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

__infer_variance__

Должна ли вариативность спецификации параметров выводиться проверяющими типы.

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

__default__

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

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

evaluate_default()

Функция evaluate, соответствующая атрибуту __default__. При прямом вызове этот метод поддерживает только формат VALUE, что эквивалентно прямому обращению к атрибуту __default__, но объект метода можно передать в annotationlib.call_evaluate_function() для вычисления значения в другом формате.

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

has_default()

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

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

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

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

Изменено в версии 3.12: Спецификации параметров теперь можно объявлять с помощью синтаксиса type parameter, введённого в PEP 695.

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

Примечание

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

См. также

class typing.ParamSpecArgs
class typing.ParamSpecKwargs

Атрибуты аргументов и именованных аргументов (keyword arguments) объекта 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=(), qualname=None)

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

Пример:

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

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

__name__

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

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

Квалифицированное имя псевдонима типа:

>>> class Class:
...     type Alias = int
...
>>> Class.Alias.__qualname__
'Class.Alias'

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

__module__

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

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

Этот атрибут доступен для записи.

Изменено в версии 3.15: Теперь этот атрибут доступен для записи.

__type_params__

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

>>> 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
evaluate_value()

Функция evaluate, соответствующая атрибуту __value__. При прямом вызове этот метод поддерживает только формат VALUE, что эквивалентно прямому доступу к атрибуту __value__, но объект метода можно передать в annotationlib.call_evaluate_function() для вычисления значения в другом формате:

>>> type Alias = undefined
>>> Alias.__value__
Traceback (most recent call last):
...
NameError: name 'undefined' is not defined
>>> from annotationlib import Format, call_evaluate_function
>>> Alias.evaluate_value(Format.VALUE)
Traceback (most recent call last):
...
NameError: name 'undefined' is not defined
>>> call_evaluate_function(Alias.evaluate_value, Format.FORWARDREF)
ForwardRef('undefined')

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

распаковка

Псевдонимы типов поддерживают распаковку со звёздочкой (star unpacking) с помощью синтаксиса *Alias. Это эквивалентно прямому использованию Unpack[Alias]:

>>> type Alias = tuple[int, str]
>>> type Unpacked = tuple[bool, *Alias]
>>> Unpacked.__value__
tuple[bool, typing.Unpack[Alias]]

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

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

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

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

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

Типы для каждого имени поля можно получить, вызвав annotationlib.get_annotations() для результирующего класса. (Имена полей находятся в атрибуте _fields, а значения по умолчанию – в атрибуте _field_defaults; оба атрибута являются частью API namedtuple().)

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

class Employee(NamedTuple):
    """Представляет сотрудника."""
    name: str
    id: int = 3

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

Подклассы NamedTuple могут быть обобщёнными (generic):

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

Обратно совместимое использование:

# Для создания обобщённого NamedTuple в Python 3.11
T = TypeVar("T")

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

# Также поддерживается функциональный синтаксис
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.9: NamedTuple теперь функция, а не класс. По-прежнему может использоваться как базовый класс, как описано выше.

Изменено в версии 3.11: Добавлена поддержка обобщённых именованных кортежей (generic namedtuples).

Изменено в версии 3.14: Использование super()__class__ замыкающей переменной) в методах подклассов NamedTuple не поддерживается и вызывает TypeError.

class typing.NewType(name, tp)

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

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

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

UserId = NewType('UserId', int)  # Объявить NewType "UserId"
first_user = UserId(1)  # "UserId" возвращает аргумент без изменений во время выполнения
__module__

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

__name__

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

__supertype__

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

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

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

class typing.Protocol(Generic)

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

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

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

Такие классы в основном используются со статическими проверяющими типов, которые распознают структурную подтипизацию (статическую утиную типизацию), например:

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

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

func(C())  # Проходит статическую проверку типов

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

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

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

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

T = TypeVar("T")

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

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

Устарело с версии 3.15, будет удалено в версии 3.20: Вызов проверок isinstance() и issubclass() для классов протоколов, которые не были явно декорированы с помощью runtime_checkable(), но наследуют от класса протокола с проверкой во время выполнения, является устаревшим. Это приведет к выбрасыванию TypeError в Python 3.20.

@typing.runtime_checkable

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

Такой протокол можно использовать с isinstance() и issubclass(). Это позволяет выполнять простую структурную проверку, очень похожую на «однофокусные» (one-trick ponies) в 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
class Iterable(Protocol):
    def __iter__(self): ...

# Без @runtime_checkable класс Reversible больше не будет проверяемым во время выполнения.
@runtime_checkable
class Reversible(Iterable, Protocol):
    def __reversed__(self): ...

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

Примечание

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: Члены протокола, проверяемого во время выполнения, теперь считаются «замороженными» во время выполнения сразу после создания класса. Динамическое добавление атрибутов (monkey-patching) в такой протокол всё ещё будет работать, но не повлияет на проверки isinstance(), сравнивающие объекты с протоколом. См. Что нового в Python 3.12 для подробностей.

Устарело с версии 3.15, будет удалено в версии 3.20: Вызов проверок isinstance() и issubclass() для классов протоколов, которые не были явно декорированы с помощью runtime_checkable(), но наследуют от класса протокола с проверкой во время выполнения, является устаревшим. Это приведет к выбрасыванию TypeError в Python 3.20.

class typing.TypedDict(dict)

Специальная конструкция для добавления подсказок типов к словарю. Во время выполнения «экземпляры TypedDict» – это просто dicts.

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

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

a: Point2D = {'x': 1, 'y': 2, 'label': 'good'}  # ОК
b: Point2D = {'z': 3, 'label': 'bad'}           # Не проходит проверку типов

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})

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

# возбуждает SyntaxError
class Point2D(TypedDict):
    in: int  # 'in' – ключевое слово
    x-y: int  # имя с дефисами

class Definition(TypedDict):
    __schema: str  # искажено до `_Definition__schema`

# ОК, функциональный синтаксис
Point2D = TypedDict('Point2D', {'in': int, 'x-y': int})
Definition = TypedDict('Definition', {'__schema': str})  # не искажается

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

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

# Альтернативный синтаксис
Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': NotRequired[str]})

Это означает, что Point2D TypedDict может не содержать ключ label.

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

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

# Альтернативный синтаксис
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

# Альтернативный синтаксис
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 является открытым, то есть он может содержать дополнительные ключи во время выполнения, помимо тех, что определены в теле класса. Аргумент класса closed можно использовать для управления этим; если closed=True, то TypedDict не может содержать дополнительные ключи.

class ClosedPoint(TypedDict, closed=True):
    x: int
    y: int

class ClosedPoint3D(ClosedPoint):  # Ошибка проверки типов: невозможно добавить ключи в закрытый TypedDict.
    z: int

Явная установка closed=False запрашивает поведение по умолчанию (открытое). Если аргумент не передан, это состояние наследуется от родительского класса.

В дополнение к открытому или закрытому состоянию, TypedDict можно настроить на наличие дополнительных элементов. Если аргумент класса extra_items установлен в тип, то TypedDict может содержать произвольные дополнительные ключи, но значения этих ключей должны быть указанного типа.

class ExtraItemsPoint(TypedDict, extra_items=int):
    x: int
    y: int

point: ExtraItemsPoint = {'x': 1, 'y': 2, 'anything': 3}  # ОК

Аргумент extra_items также наследуется через подклассы. По умолчанию он не установлен, и его нельзя использовать вместе с аргументом closed.

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

class X(TypedDict):
    x: int

class Y(TypedDict):
    y: int

class Z(object): pass  # Класс, не являющийся TypedDict

class XY(X, Y): pass  # ОК

class XZ(X, Z): pass  # вызывает 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 можно анализировать с помощью annotationlib.get_annotations() (см. Рекомендации по аннотациям для получения дополнительной информации о лучших практиках аннотаций) и следующих атрибутов:

__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_keys__

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

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

__mutable_keys__

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

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

__closed__

Значение аргумента класса closed. Может быть True, False или None.

__extra_items__

Значение аргумента класса extra_items. Может быть валидным типом или NoExtraItems.

Дополнительные примеры и подробные правила приведены в разделе TypedDict документации typing.

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

Изменено в версии 3.9: TypedDict теперь функция, а не класс. По-прежнему может использоваться как базовый класс, как описано выше.

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

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

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

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

Изменено в версии 3.15: Добавлена поддержка аргументов класса closed и extra_items. См. PEP 728.

ПротоколыProtocols

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

class typing.SupportsAbs

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

class typing.SupportsBytes

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

class typing.SupportsComplex

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

class typing.SupportsFloat

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

class typing.SupportsIndex

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

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

class typing.SupportsInt

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

class typing.SupportsRound

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

Абстрактные базовые классы и протоколы для работы с вводом-выводомABCs and Protocols for working with I/O

class typing.IO[AnyStr]
class typing.TextIO
class typing.BinaryIO

Обобщённый класс IO[AnyStr] и его подклассы TextIO(IO[str]) и BinaryIO(IO[bytes]) представляют типы потоков ввода-вывода (I/O), например возвращаемые open(). Обратите внимание: эти классы не являются протоколами, и их интерфейс довольно обширен.

Протоколы io.Reader и io.Writer предоставляют более простую альтернативу для типов аргументов, когда доступны только методы read() или write() соответственно:

def read_and_write(reader: Reader[str], writer: Writer[bytes]):
    data = reader.read()
    writer.write(data.encode())

Также рассмотрите использование collections.abc.Iterable для итерации по строкам входного потока:

def read_config(stream: Iterable[str]):
    for line in stream:
        ...

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

typing.cast(typ, val)

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

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

typing.assert_type(val, typ, /)

Запросить у статического проверщика типов подтверждение, что val имеет выведенный тип typ.

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

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

def greet(name: str) -> None:
    assert_type(name, str)  # ОК, выведенный тип `name` – `str`
    assert_type(name, int)  # ошибка проверки типов

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

def complex_function(arg: object):
    # Выполнить сложную логику сужения типа,
    # после чего ожидается, что выведенный тип станет `int`
    ...
    # Проверить, правильно ли проверщик типов понимает нашу функцию
    assert_type(arg, int)

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

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 и ничем иным.

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

См. также

В разделе Unreachable Code and Exhaustiveness Checking содержится дополнительная информация о проверке полноты с помощью статической типизации.

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

typing.reveal_type(obj, /)

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

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

x: int = 1
reveal_type(x)  # Раскрытый тип – "builtins.int"

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

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

x = reveal_type(1)  # выводит «Runtime type is int»
print(x)  # выводит "1"

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

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

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

@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

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

alias

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

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

Подробнее см. PEP 681.

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

@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):
    ...  # здесь находится фактическая реализация

Подробнее и сравнение с другими семантиками типизации см. PEP 484.

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

typing.get_overloads(func)

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

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

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

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

typing.clear_overloads()

Очищает все зарегистрированные перегрузки во внутреннем реестре.

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

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

@typing.final

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

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

Например:

class Base:
    @final
    def done(self) -> None:
        ...
class Sub(Base):
    def done(self) -> None:  # Ошибка, выдаваемая проверщиком типов
        ...

@final
class Leaf:
    ...
class Other(Leaf):  # Ошибка, выдаваемая проверщиком типов
    ...

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

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

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

@typing.no_type_check

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

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

@no_type_check изменяет декорированный объект на месте.

@typing.override

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

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

Например:

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

class Sub(Base):
    @override
    def log_status(self) -> None:  # ОК: переопределяет Base.log_status
        ...

    @override
    def done(self) -> None:  # Ошибка, выдаваемая проверщиком типов
        ...

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

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

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

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

@typing.disjoint_base

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

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

Например:

@disjoint_base
class Disjoint1: pass

@disjoint_base
class Disjoint2: pass

class Disjoint3(Disjoint1, Disjoint2): pass  # Ошибка проверки типов

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

Соответствующее понятие времени выполнения – сплошной базовый класс (см. Множественное наследование). Классы, являющиеся сплошными базовыми во время выполнения, можно пометить с помощью @disjoint_base в файлах заглушек. Пользователи также могут помечать другие классы как непересекающиеся базовые, чтобы указать типизаторам, что множественное наследование с другими непересекающимися базовыми не должно разрешаться.

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

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

@typing.type_check_only

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

Сам этот декоратор недоступен во время выполнения. Он в основном предназначен для пометки классов, определённых в файлах заглушек типов (type stub), если реализация возвращает экземпляр закрытого класса:

@type_check_only
class Response:  # приватный или недоступный во время выполнения
    code: int
    def get_header(self, name: str) -> str: ...

def fetch_response() -> Response: ...

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

Вспомогательные функции для интроспекцииIntrospection helpers

typing.get_type_hints(obj, globalns=None, localns=None, include_extras=False, *, format=Format.VALUE)

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

Часто это то же самое, что и annotationlib.get_annotations(), но эта функция вносит следующие изменения в словарь аннотаций:

  • Прямые ссылки (forward references), закодированные как строковые литералы или объекты ForwardRef, обрабатываются путём вычисления их в пространствах имён globalns, localns и (где применимо) пространстве имён obj’s параметра типа. Если globalns или localns не заданы, соответствующие словари пространств имён выводятся из obj.

  • None заменяется на types.NoneType.

  • Если к obj был применён @no_type_check, возвращается пустой словарь.

  • Если obj – это класс C, функция возвращает словарь, объединяющий аннотации из базовых классов C с аннотациями, непосредственно указанными в C. Это делается путём обхода C.__mro__ и итеративного объединения аннотаций каждого базового класса. Аннотации классов, встречающихся раньше в порядке разрешения методов, всегда имеют приоритет над аннотациями классов, встречающихся позже в порядке разрешения методов.

  • Функция рекурсивно заменяет все вхождения Annotated[T, ...], Required[T], NotRequired[T] и ReadOnly[T] на T, если только include_extras не установлен в True (см. Annotated для получения дополнительной информации).

Внимание

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

Примечание

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

Примечание

Вызов get_type_hints() для экземпляра не поддерживается. Чтобы получить аннотации для экземпляра, вызовите get_type_hints() для класса этого экземпляра (например, get_type_hints(type(obj))).

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

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

Изменено в версии 3.14: Добавлен параметр format. Подробнее см. в документации annotationlib.get_annotations().

Изменено в версии 3.14: Вызов get_type_hints() на экземплярах больше не поддерживается. Некоторые экземпляры принимались в более ранних версиях как недокументированная деталь реализации.

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 является объединением (union) или 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

assert is_protocol(P)
assert not is_protocol(int)

Эта функция возвращает true только для классов Protocol, а не для их обобщённых псевдонимов.

class GenericP[T](Protocol):
    def a(self) -> T: ...
    b: int

assert not is_protocol(GenericP[int])

Добавлено в версии 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 – это фабрика для создания типизированных словарей,
# а не сам типизированный словарь
assert not is_typeddict(TypedDict)

Эта функция возвращает true только для классов TypedDict, а не для их обобщённых псевдонимов.

class GenericFilm[T](TypedDict):
    title: str
    year: T

assert not is_typeddict(GenericFilm[int])

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

class typing.ForwardRef

Класс для внутреннего представления строковых прямых ссылок в typing.

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

Примечание

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

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

Изменено в версии 3.14: Теперь это псевдоним для annotationlib.ForwardRef. Были изменены некоторые недокументированные особенности поведения этого класса; например, после вычисления ForwardRef вычисленное значение больше не кешируется.

typing.evaluate_forward_ref(forward_ref, *, owner=None, globals=None, locals=None, type_params=None, format=annotationlib.Format.VALUE)

Вычисляет annotationlib.ForwardRef как подсказку типа.

Это похоже на вызов annotationlib.ForwardRef.evaluate(), но, в отличие от этого метода, evaluate_forward_ref() также рекурсивно вычисляет прямые ссылки, вложенные в подсказку типа.

Значение параметров owner, globals, locals, type_params и format см. в документации annotationlib.ForwardRef.evaluate().

Внимание

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

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

typing.NoDefault

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

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

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

typing.NoExtraItems

Объект sentinel, указывающий, что у TypedDict отсутствует аргумент класса extra_items.

>>> from typing import TypedDict, NoExtraItems
>>> class Point(TypedDict):
...     x: int
...     y: int
...
>>> Point.__extra_items__ is NoExtraItems
True

КонстантаConstant

typing.TYPE_CHECKING

Специальная константа, которая считается равной True статическими анализаторами типов. Во время выполнения она равна False.

Модуль, который дорого импортировать и который содержит только типы для аннотаций, можно безопасно импортировать внутри блока if TYPE_CHECKING:. Это предотвращает фактический импорт модуля во время выполнения; аннотации не вычисляются с нетерпением (см. PEP 649), поэтому использование неопределённых символов в аннотациях безвредно – если только вы не станете анализировать их позже. Ваш инструмент статического анализа типов установит TYPE_CHECKING в True во время статического анализа, что означает, что модуль будет импортирован, а типы будут корректно проверены во время такого анализа.

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

if TYPE_CHECKING:
    import expensive_mod

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

Если вам время от времени нужно просматривать аннотации типов во время выполнения, которые могут содержать неопределённые символы, используйте annotationlib.get_annotations() с параметром format равным annotationlib.Format.STRING или annotationlib.Format.FORWARDREF, чтобы безопасно получить аннотации без возникновения NameError.

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

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

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

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

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

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

Псевдонимы встроенных типовAliases to built-in types

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

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

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

Deprecated since version 3.9: builtins.dict now supports subscripting ([]). See PEP 585 and Generic Alias Type.

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

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

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

Deprecated since version 3.9: builtins.list now supports subscripting ([]). See PEP 585 and Generic Alias Type.

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

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

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

Deprecated since version 3.9: builtins.set now supports subscripting ([]). See PEP 585 and Generic Alias Type.

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

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

Deprecated since version 3.9: builtins.frozenset now supports subscripting ([]). See PEP 585 and Generic Alias Type.

typing.Tuple

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

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

Deprecated since version 3.9: builtins.tuple now supports subscripting ([]). See PEP 585 and Generic Alias Type.

class typing.Type(Generic[CT_co])

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

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

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

Deprecated since version 3.9: builtins.type now supports subscripting ([]). See PEP 585 and Generic Alias Type.

Псевдонимы типов в collectionsAliases to types in collections

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

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

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

Deprecated since version 3.9: collections.defaultdict now supports subscripting ([]). See PEP 585 and Generic Alias Type.

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

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

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

Deprecated since version 3.9: collections.OrderedDict now supports subscripting ([]). See PEP 585 and Generic Alias Type.

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

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

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

Deprecated since version 3.9: collections.ChainMap now supports subscripting ([]). See PEP 585 and Generic Alias Type.

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

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

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

Deprecated since version 3.9: collections.Counter now supports subscripting ([]). See PEP 585 and Generic Alias Type.

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

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

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

Deprecated since version 3.9: collections.deque now supports subscripting ([]). See PEP 585 and Generic Alias Type.

Псевдонимы для других конкретных типовAliases to other concrete types

class typing.Pattern
class typing.Match

Устаревшие псевдонимы, соответствующие типам возвращаемых значений из re.compile() и re.search().

Эти типы (и соответствующие функции) являются обобщёнными относительно AnyStr. Pattern может быть специализирован как Pattern[str] или Pattern[bytes]; Match может быть специализирован как Match[str] или Match[bytes].

Устарело с версии 3.9: Классы Pattern и Match из re теперь поддерживают []. См. PEP 585 и Generic Alias Type.

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.abcAliases to container ABCs in collections.abc

class typing.AbstractSet(Collection[T_co])

Устаревший псевдоним collections.abc.Set.

Deprecated since version 3.9: collections.abc.Set now supports subscripting ([]). See PEP 585 and Generic Alias Type.

class typing.ByteString(Sequence[int])

Устаревший псевдоним collections.abc.ByteString.

При помощи isinstance(obj, collections.abc.Buffer) проверяется, реализует ли obj протокол буфера во время выполнения. Для аннотаций типов используйте Buffer или объединение, явно перечисляющее поддерживаемые типы (например, bytes | bytearray | memoryview).

ByteString изначально задумывался как абстрактный класс, служащий супертипом как для bytes, так и для bytearray. Однако, поскольку у ABC никогда не было методов, знание того, что объект является экземпляром ByteString, никогда не давало полезной информации об объекте. Другие распространённые типы буферов, такие как memoryview, также никогда не воспринимались как подтипы ByteString (ни во время выполнения, ни статическими проверками типов).

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

Устарело с версии 3.9, будет удалено в версии 3.17.

class typing.Collection(Sized, Iterable[T_co], Container[T_co])

Устаревший псевдоним collections.abc.Collection.

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

Deprecated since version 3.9: collections.abc.Collection now supports subscripting ([]). See PEP 585 and Generic Alias Type.

class typing.Container(Generic[T_co])

Устаревший псевдоним collections.abc.Container.

Deprecated since version 3.9: collections.abc.Container now supports subscripting ([]). See PEP 585 and Generic Alias Type.

class typing.ItemsView(MappingView, AbstractSet[tuple[KT_co, VT_co]])

Устаревший псевдоним collections.abc.ItemsView.

Deprecated since version 3.9: collections.abc.ItemsView now supports subscripting ([]). See PEP 585 and Generic Alias Type.

class typing.KeysView(MappingView, AbstractSet[KT_co])

Устаревший псевдоним collections.abc.KeysView.

Deprecated since version 3.9: collections.abc.KeysView now supports subscripting ([]). See PEP 585 and Generic Alias Type.

class typing.Mapping(Collection[KT], Generic[KT, VT_co])

Устаревший псевдоним collections.abc.Mapping.

Deprecated since version 3.9: collections.abc.Mapping now supports subscripting ([]). See PEP 585 and Generic Alias Type.

class typing.MappingView(Sized)

Устаревший псевдоним collections.abc.MappingView.

Deprecated since version 3.9: collections.abc.MappingView now supports subscripting ([]). See PEP 585 and Generic Alias Type.

class typing.MutableMapping(Mapping[KT, VT])

Устаревший псевдоним collections.abc.MutableMapping.

Deprecated since version 3.9: collections.abc.MutableMapping now supports subscripting ([]). See PEP 585 and Generic Alias Type.

class typing.MutableSequence(Sequence[T])

Устаревший псевдоним collections.abc.MutableSequence.

Deprecated since version 3.9: collections.abc.MutableSequence now supports subscripting ([]). See PEP 585 and Generic Alias Type.

class typing.MutableSet(AbstractSet[T])

Устаревший псевдоним collections.abc.MutableSet.

Deprecated since version 3.9: collections.abc.MutableSet now supports subscripting ([]). See PEP 585 and Generic Alias Type.

class typing.Sequence(Reversible[T_co], Collection[T_co])

Устаревший псевдоним collections.abc.Sequence.

Deprecated since version 3.9: collections.abc.Sequence now supports subscripting ([]). See PEP 585 and Generic Alias Type.

class typing.ValuesView(MappingView, Collection[_VT_co])

Устаревший псевдоним collections.abc.ValuesView.

Deprecated since version 3.9: collections.abc.ValuesView now supports subscripting ([]). See PEP 585 and Generic Alias Type.

Псевдонимы для асинхронных ABC в collections.abcAliases to asynchronous ABCs in collections.abc

class typing.Coroutine(Awaitable[ReturnType], Generic[YieldType, SendType, ReturnType])

Устаревший псевдоним collections.abc.Coroutine.

See Annotating generators and coroutines for details on using collections.abc.Coroutine and typing.Coroutine in type annotations.

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

Deprecated since version 3.9: collections.abc.Coroutine now supports subscripting ([]). See PEP 585 and Generic Alias Type.

class typing.AsyncGenerator(AsyncIterator[YieldType], Generic[YieldType, SendType])

Устаревший псевдоним collections.abc.AsyncGenerator.

See Annotating generators and coroutines for details on using collections.abc.AsyncGenerator and typing.AsyncGenerator in type annotations.

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

Deprecated since version 3.9: collections.abc.AsyncGenerator now supports subscripting ([]). See PEP 585 and Generic Alias Type.

Изменено в версии 3.13: параметр SendType теперь имеет значение по умолчанию.

class typing.AsyncIterable(Generic[T_co])

Устаревший псевдоним collections.abc.AsyncIterable.

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

Deprecated since version 3.9: collections.abc.AsyncIterable now supports subscripting ([]). See PEP 585 and Generic Alias Type.

class typing.AsyncIterator(AsyncIterable[T_co])

Устаревший псевдоним collections.abc.AsyncIterator.

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

Deprecated since version 3.9: collections.abc.AsyncIterator now supports subscripting ([]). See PEP 585 and Generic Alias Type.

class typing.Awaitable(Generic[T_co])

Устаревший псевдоним collections.abc.Awaitable.

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

Deprecated since version 3.9: collections.abc.Awaitable now supports subscripting ([]). See PEP 585 and Generic Alias Type.

Псевдонимы для других ABC в collections.abcAliases to other ABCs in collections.abc

class typing.Iterable(Generic[T_co])

Устаревший псевдоним collections.abc.Iterable.

Deprecated since version 3.9: collections.abc.Iterable now supports subscripting ([]). See PEP 585 and Generic Alias Type.

class typing.Iterator(Iterable[T_co])

Устаревший псевдоним collections.abc.Iterator.

Deprecated since version 3.9: collections.abc.Iterator now supports subscripting ([]). See PEP 585 and Generic Alias Type.

typing.Callable

Устаревший псевдоним collections.abc.Callable.

See Annotating callable objects for details on how to use collections.abc.Callable and typing.Callable in type annotations.

Deprecated since version 3.9: collections.abc.Callable now supports subscripting ([]). See PEP 585 and Generic Alias Type.

Changed in version 3.10: Callable now supports ParamSpec and Concatenate. See PEP 612 for more details.

class typing.Generator(Iterator[YieldType], Generic[YieldType, SendType, ReturnType])

Устаревший псевдоним collections.abc.Generator.

See Annotating generators and coroutines for details on using collections.abc.Generator and typing.Generator in type annotations.

Deprecated since version 3.9: collections.abc.Generator now supports subscripting ([]). See PEP 585 and Generic Alias Type.

Изменено в версии 3.13: Добавлены значения по умолчанию для типов send и return.

class typing.Hashable

Устаревший псевдоним collections.abc.Hashable.

Устарело с версии 3.12: Используйте непосредственно collections.abc.Hashable.

class typing.Reversible(Iterable[T_co])

Устаревший псевдоним collections.abc.Reversible.

Deprecated since version 3.9: collections.abc.Reversible now supports subscripting ([]). See PEP 585 and Generic Alias Type.

class typing.Sized

Устаревший псевдоним collections.abc.Sized.

Устарело с версии 3.12: Используйте непосредственно collections.abc.Sized.

Псевдонимы для contextlib ABCsAliases to contextlib ABCs

class typing.ContextManager(Generic[T_co, ExitT_co])

Устаревший псевдоним contextlib.AbstractContextManager.

Первый параметр типа, T_co, представляет тип, возвращаемый методом __enter__(). Необязательный второй параметр типа, ExitT_co, по умолчанию равный bool | None, представляет тип, возвращаемый методом __exit__().

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

Deprecated since version 3.9: contextlib.AbstractContextManager now supports subscripting ([]). See PEP 585 and Generic Alias Type.

Изменено в версии 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.

Deprecated since version 3.9: contextlib.AbstractAsyncContextManager now supports subscripting ([]). See PEP 585 and Generic Alias Type.

Изменено в версии 3.13: Добавлен необязательный второй параметр типа, AExitT_co.

Хронология устаревания основных возможностейDeprecation Timeline of Major Features

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

Возможность

Устарело в

Планируемое удаление

PEP/issue

typing версии стандартных коллекций

3.9

Не определено (см. устаревшие псевдонимы для дополнительной информации)

PEP 585

typing.ByteString

3.9

3.17

gh-91896

typing.Text

3.11

Не определено

gh-92332

typing.Hashable и typing.Sized

3.12

Не определено

gh-94309

typing.TypeAlias

3.12

Не определено

PEP 695

typing.AnyStr

3.13

3.18

gh-105578