Spec-Zone.ru › Python 3.12

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

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

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

Примечание

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

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

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

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

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

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

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

См. также

«Шпаргалка по аннотациям типов»

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

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

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

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

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

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

Актуальную официальную спецификацию системы типов Python можно найти в документе «Спецификация системы типов Python».

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

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

type Vector = list[float]

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

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

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

from collections.abc import Sequence

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

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

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

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

Vector = list[float]

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

from typing import TypeAlias

Vector: TypeAlias = list[float]

NewType

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

from typing import NewType

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

Средство статической проверки типов будет рассматривать новый тип как подкласс исходного типа. Это помогает выявлять логические ошибки:

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

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

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

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

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

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

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

Создавать подкласс Derived нельзя:

from typing import NewType

UserId = NewType('UserId', int)

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

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

from typing import NewType

UserId = NewType('UserId', int)

ProUserId = NewType('ProUserId', UserId)

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

Подробнее см. в PEP 484.

Примечание

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

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

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

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

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

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

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

Например:

from collections.abc import Callable, Awaitable

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

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

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

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

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

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

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

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

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

from collections.abc import Iterable
from typing import Protocol

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

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

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

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

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

Изменено в версии 3.10: Callable теперь поддерживает ParamSpec и Concatenate. Подробнее см. в PEP 612.

См. также

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

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

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

from collections.abc import Mapping, Sequence

class Employee: ...

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

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

from collections.abc import Sequence

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

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

from collections.abc import Sequence
from typing import TypeVar

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

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

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

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

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

from collections.abc import Mapping

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Аннотирование генераторов и сопрограмм

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

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

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

Если ваш генератор выдаёт только значения, задайте для SendType и ReturnType значение None:

def infinite_stream(start: int) -> Generator[int, 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]):

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

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

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

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

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

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

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

from logging import Logger

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

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

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

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

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

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

from typing import TypeVar, Generic

T = TypeVar('T')

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

У обобщённых классов есть методы __class_getitem__(), поэтому их можно параметризовать во время выполнения (например, как LoggedVar[int] ниже):

from collections.abc import Iterable

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

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

from typing import TypeVar, Generic, Sequence

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

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

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

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

from typing import TypeVar, Generic
...

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

T = TypeVar('T')

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

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

from collections.abc import Sized

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

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

from collections.abc import Mapping

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

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

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

from collections.abc import Iterable

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

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

from collections.abc import Iterable

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

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

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

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

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

from collections.abc import Iterable
from typing import TypeVar

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

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

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

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

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

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

from typing import ParamSpec, Generic

P = ParamSpec('P')

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

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

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

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

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

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

Тип Any

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

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

from typing import Any

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

s: str = ''
s = a           # OK

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

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

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

def legacy_parser(text):
    ...
    return data

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

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

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

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

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

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

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

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

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

Номинальная и структурная подтипизация

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

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

from collections.abc import Sized, Iterable, Iterator

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

PEP 544 решает эту проблему, позволяя писать приведённый выше код без явных базовых классов в определении класса. Благодаря этому средства статической проверки типов могут неявно считать Bucket подтипом обоих классов: Sized и Iterable[int]. Это называется структурной подтипизацией (или статической «утино-типизацией»):

from collections.abc import Iterator, Iterable

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

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

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

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

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

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

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

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

typing.Any

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

  • Любой тип совместим с Any.
  • Any совместим с любым типом.

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

typing.AnyStr

Ограниченная переменная типа.

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

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

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

Например:

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

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

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

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

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

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

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

Пример:

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

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

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

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

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

typing.Never
typing.NoReturn

Never и NoReturn обозначают нижний тип — тип, у которого нет элементов.

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

from typing import Never  # or NoReturn

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

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

from typing import Never  # or NoReturn

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

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

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

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

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

typing.Self

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

Например:

from typing import Self, reveal_type

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

class SubclassOfFoo(Foo): pass

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

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

from typing import TypeVar

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

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

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

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

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

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

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

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

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

typing.TypeAlias

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

Например:

from typing import TypeAlias

Factors: TypeAlias = list[int]

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

from typing import Generic, TypeAlias, TypeVar

T = TypeVar("T")

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

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

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

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

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

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

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

typing.Union

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

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

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

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

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

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

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

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

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

typing.Optional

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

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

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

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

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

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

typing.Concatenate

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

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

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

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

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

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

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

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

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

См. также

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

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

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

Например:

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

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

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

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

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

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

typing.ClassVar

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

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

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

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

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

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

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

typing.Final

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

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

Например:

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

class Connection:
    TIMEOUT: Final[int] = 10

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

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

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

typing.Required

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

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

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

typing.NotRequired

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

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

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

typing.Annotated

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

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

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

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

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

Annotated[<type>, <metadata>]

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

@dataclass
class ValueRange:
    lo: int
    hi: int

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

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

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

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

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

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

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

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

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

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

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

    Это было бы эквивалентно следующему:

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

    где T1, T2 и т. д. — это TypeVars. Такая запись недопустима: в Annotated следует передавать только один тип.

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

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

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

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

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

    >>> get_origin(Password)
    <class 'typing.Annotated'>
    

См. также

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

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

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

typing.TypeGuard

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

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

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

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

Иногда бывает удобно использовать пользовательскую логическую функцию в качестве охранника типа. Чтобы сообщить статическим средствам проверки типов о таком намерении, в качестве типа возвращаемого значения этой функции следует указать TypeGuard[...].

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

  1. Возвращаемое значение — логическое.
  2. Если возвращаемое значение равно True, тип её аргумента — это тип, указанный внутри TypeGuard.

Например:

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

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

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

Иными словами, форма def foo(arg: TypeA) -> TypeGuard[TypeB]: ... означает, что если foo(arg) возвращает True, то тип arg сужается с TypeA до TypeB.

Примечание

TypeB не обязательно должен быть более узким типом, чем TypeA, — он может быть даже более широким. Основная причина этого — возможность сужать, например, list[object] до list[str], хотя последний не является подтипом первого, поскольку list инвариантен. Ответственность за написание безопасных с точки зрения типов охранников типов лежит на пользователе.

TypeGuard также работает с переменными типа. Подробнее см. PEP 647.

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

typing.Unpack

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

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

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

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

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

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

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

from typing import TypedDict, Unpack

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

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

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

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

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

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

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

class typing.Generic

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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


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


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

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

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

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

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

class StringSubclass(str):
    pass

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

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

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

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

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

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

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

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

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

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

__name__

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

__covariant__

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

__contravariant__

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

__infer_variance__

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

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

__bound__

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

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

__constraints__

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

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

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

class typing.TypeVarTuple(name)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

class Array2[*Shape, DType]:  # This would also be fine
    pass

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

float_array_1d: Array[float, Height] = Array()     # Totally fine
int_array_2d: Array[int, Height, Width] = Array()  # Yup, fine too

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

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

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

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

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

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

__name__

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

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

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

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

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

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

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

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

P = ParamSpec('P')

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

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

from collections.abc import Callable
import logging

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

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

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

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

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

__name__

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

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

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

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

Примечание

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

См. также

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

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

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

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

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

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

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

Пример:

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

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

__name__

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

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

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

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

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

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

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

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

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

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

class typing.NamedTuple

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Использование, обеспечивающее обратную совместимость:

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

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

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

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

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

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

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

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

class typing.NewType(name, tp)

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

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

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

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

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

__name__

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

__supertype__

Тип, на основе которого создан новый тип.

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

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

class typing.Protocol(Generic)

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

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

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

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

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

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

func(C())  # Passes static type check

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

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

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

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

T = TypeVar("T")

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

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

@typing.runtime_checkable

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

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

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

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

@runtime_checkable
class Named(Protocol):
    name: str

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

Примечание

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

Примечание

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

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

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

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

class typing.TypedDict(dict)

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

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

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

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

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

Чтобы использовать эту возможность в старых версиях Python, не поддерживающих PEP 526, TypedDict поддерживает две дополнительные эквивалентные синтаксические формы:

  • Использование литерала dict в качестве второго аргумента:

    Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str})
    
  • Использование ключевых аргументов:

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

    Устарело с версии 3.11, будет удалено в версии 3.13: Синтаксис с ключевыми аргументами устарел в версии 3.11 и будет удалён в версии 3.13. Он также может не поддерживаться статическими средствами проверки типов.

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

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

class Definition(TypedDict):
    __schema: str  # mangled to `_Definition__schema`

# OK, functional syntax
Point2D = TypedDict('Point2D', {'in': int, 'x-y': int})
Definition = TypedDict('Definition', {'__schema': str})  # not mangled

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

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

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

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

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

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

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

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

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

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

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

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

class Point3D(Point2D):
    z: int

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

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

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

class X(TypedDict):
    x: int

class Y(TypedDict):
    y: int

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

class XY(X, Y): pass  # OK

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

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

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

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

T = TypeVar("T")

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

Получить сведения о TypedDict можно через словари аннотаций (подробнее о рекомендуемых практиках работы с аннотациями см. в разделе Рекомендации по аннотациям), а также через __total__, __required_keys__ и __optional_keys__.

__total__

Point2D.__total__ содержит значение аргумента total. Пример:

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

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

__required_keys__

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

__optional_keys__

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

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

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

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

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

Примечание

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

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

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

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

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

Протоколы

Модуль 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__, ковариантным по типу возвращаемого значения.

Абстрактные базовые классы для работы с вводом-выводом

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

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

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

typing.cast(typ, val)

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

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

typing.assert_type(val, typ, /)

Попросить статический анализатор типов подтвердить, что выведенный тип val — это typ.

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

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

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

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

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

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

typing.assert_never(arg, /)

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

Пример:

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

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

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

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

См. также

В статье Недостижимый код и проверка полноты вариантов содержится дополнительная информация о проверке полноты вариантов при статической проверке типов.

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

typing.reveal_type(obj, /)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@create_model
class CustomerModel:
    id: int
    name: str

Для базового класса:

@dataclass_transform()
class ModelBase: ...

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

Для метакласса:

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

class ModelBase(metaclass=ModelMeta): ...

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

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

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

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

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

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

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

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

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

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

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

Описание

init

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

default

Задаёт значение поля по умолчанию.

default_factory

Задаёт функцию обратного вызова, которая во время выполнения возвращает значение поля по умолчанию. Если не указаны ни default, ни default_factory, считается, что у поля нет значения по умолчанию, и при создании экземпляра класса ему необходимо присвоить значение.

factory

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

kw_only

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

alias

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

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

Дополнительные сведения см. в PEP 681.

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

@typing.overload

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

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

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

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

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

Дополнительные сведения и сравнение с другими семантическими правилами типизации см. в PEP 484.

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

typing.get_overloads(func)

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

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

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

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

typing.clear_overloads()

Удаляет все зарегистрированные перегрузки из внутреннего реестра.

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

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

@typing.final

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

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

Например:

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

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

Во время выполнения эти свойства не проверяются. Дополнительные сведения см. в PEP 591.

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

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

@typing.no_type_check

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

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

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

@typing.no_type_check_decorator

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

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

@typing.override

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

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

Например:

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

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

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

Во время выполнения это свойство не проверяется.

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

Дополнительные сведения см. в PEP 698.

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

@typing.type_check_only

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

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

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

def fetch_response() -> Response: ...

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

Вспомогательные средства интроспекции

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

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

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

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

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

Примечание

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

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

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

typing.get_origin(tp)

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

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

Примеры:

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

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

typing.get_args(tp)

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

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

Примеры:

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

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

typing.is_typeddict(tp)

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

Например:

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

assert is_typeddict(Film)
assert not is_typeddict(list | str)

# TypedDict is a factory for creating typed dicts,
# not a typed dict itself
assert not is_typeddict(TypedDict)

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

class typing.ForwardRef

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

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

Примечание

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

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

Константа

typing.TYPE_CHECKING

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

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

if TYPE_CHECKING:
    import expensive_mod

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

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

Примечание

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

typing.Tuple

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

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

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

class typing.Type(Generic[CT_co])

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Псевдонимы других конкретных типов

Устарело с версии 3.8, будет удалено в версии 3.13: Пространство имён typing.io объявлено устаревшим и будет удалено. Эти типы следует импортировать непосредственно из typing.

class typing.Pattern
class typing.Match

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

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

Устарело с версии 3.8, будет удалено в версии 3.13: Пространство имён typing.re объявлено устаревшим и будет удалено. Эти типы следует импортировать непосредственно из typing.

Устарело с версии 3.9: Классы Pattern и Match из re теперь поддерживают []. См. PEP 585 и Тип обобщённого псевдонима.

class typing.Text

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

Text предоставлен для обеспечения обратной совместимости кода Python 2: в Python 2 Text является псевдонимом для unicode.

Используйте Text, чтобы указать, что значение должно содержать строку Unicode способом, совместимым с Python 2 и Python 3:

def add_unicode_checkmark(text: Text) -> Text:
    return text + u' \u2713'

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

Устарело с версии 3.11: Python 2 больше не поддерживается, и большинство средств проверки типов также больше не проверяют типы в коде Python 2. Удаление псевдонима пока не планируется, но пользователям рекомендуется использовать str вместо Text.

Псевдонимы абстрактных базовых классов контейнеров из collections.abc

class typing.AbstractSet(Collection[T_co])

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

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

class typing.ByteString(Sequence[int])

Этот тип представляет типы bytes, bytearray и memoryview, представляющие последовательности байтов.

Устарело с версии 3.9, будет удалено в версии 3.14: Предпочтительно использовать collections.abc.Buffer или объединение, например bytes | bytearray | memoryview.

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

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

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

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

class typing.Container(Generic[T_co])

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

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

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

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

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

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

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

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

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

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

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

class typing.MappingView(Sized)

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

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

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

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

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

class typing.MutableSequence(Sequence[T])

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

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

class typing.MutableSet(AbstractSet[T])

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

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

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

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

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

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

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

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

Псевдонимы асинхронных ABC в collections.abc

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

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

Подробные сведения об использовании collections.abc.Coroutine и typing.Coroutine в аннотациях типов см. в разделе Аннотирование генераторов и сопрограмм.

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

Устарело с версии 3.9: collections.abc.Coroutine теперь поддерживает параметризацию ([]). См. PEP 585 и Обобщённый тип псевдонима.

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

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

Подробные сведения об использовании collections.abc.AsyncGenerator и typing.AsyncGenerator в аннотациях типов см. в разделе Аннотирование генераторов и сопрограмм.

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

Устарело с версии 3.9: collections.abc.AsyncGenerator теперь поддерживает параметризацию ([]). См. PEP 585 и Обобщённый тип псевдонима.

class typing.AsyncIterable(Generic[T_co])

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

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

Устарело с версии 3.9: collections.abc.AsyncIterable теперь поддерживает параметризацию ([]). См. PEP 585 и Обобщённый тип псевдонима.

class typing.AsyncIterator(AsyncIterable[T_co])

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

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

Устарело с версии 3.9: collections.abc.AsyncIterator теперь поддерживает параметризацию ([]). См. PEP 585 и Обобщённый тип псевдонима.

class typing.Awaitable(Generic[T_co])

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

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

Устарело с версии 3.9: collections.abc.Awaitable теперь поддерживает параметризацию ([]). См. PEP 585 и Обобщённый тип псевдонима.

Псевдонимы других ABC в collections.abc

class typing.Iterable(Generic[T_co])

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

Устарело с версии 3.9: collections.abc.Iterable теперь поддерживает параметризацию ([]). См. PEP 585 и Обобщённый тип псевдонима.

class typing.Iterator(Iterable[T_co])

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

Устарело с версии 3.9: collections.abc.Iterator теперь поддерживает параметризацию ([]). См. PEP 585 и Обобщённый тип псевдонима.

typing.Callable

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

Подробные сведения об использовании collections.abc.Callable и typing.Callable в аннотациях типов см. в разделе Аннотирование вызываемых объектов.

Устарело с версии 3.9: collections.abc.Callable теперь поддерживает параметризацию ([]). См. PEP 585 и Обобщённый тип псевдонима.

Изменено в версии 3.10: Callable теперь поддерживает ParamSpec и Concatenate. Дополнительные сведения см. в PEP 612.

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

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

Подробные сведения об использовании collections.abc.Generator и typing.Generator в аннотациях типов см. в разделе Аннотирование генераторов и сопрограмм.

Устарело с версии 3.9: collections.abc.Generator теперь поддерживает параметризацию ([]). См. PEP 585 и Обобщённый тип псевдонима.

class typing.Hashable

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

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

class typing.Reversible(Iterable[T_co])

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

Устарело с версии 3.9: collections.abc.Reversible теперь поддерживает параметризацию ([]). См. PEP 585 и Обобщённый тип псевдонима.

class typing.Sized

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

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

Псевдонимы ABC из contextlib

class typing.ContextManager(Generic[T_co])

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

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

Устарело с версии 3.9: contextlib.AbstractContextManager теперь поддерживает параметризацию ([]). См. PEP 585 и Обобщённый тип псевдонима.

class typing.AsyncContextManager(Generic[T_co])

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

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

Устарело с версии 3.9: contextlib.AbstractAsyncContextManager теперь поддерживает параметризацию ([]). См. PEP 585 и Обобщённый тип псевдонима.

Сроки вывода из употребления основных возможностей

Некоторые возможности в typing устарели и могут быть удалены в будущей версии Python. В следующей таблице для удобства приведены основные устаревшие возможности. Эта информация может измениться; перечислены не все устаревшие возможности.

Возможность

Устарела в версии

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

PEP/issue

Подмодули typing.io и typing.re

3.8

3.13

bpo-38291

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

3.9

Не определено (дополнительные сведения см. в разделе Устаревшие псевдонимы)

PEP 585

typing.ByteString

3.9

3.14

gh-91896

typing.Text

3.11

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

gh-92332

typing.Hashable и typing.Sized

3.12

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

gh-94309

typing.TypeAlias

3.12

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

PEP 695

© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/library/typing.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API