> **Источник:** https://python-all.ru/3.5/library/typing.html
>
> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.

---

# 26.1. [`typing`](https://python-all.ru/3.5/library/typing.html#module-typing) – Поддержка подсказок типов

Новое в версии 3.5.

**Исходный код:** [Lib/typing.py](https://python-all.ru/src/3.5/Lib/typing.py)

---

Этот модуль поддерживает подсказки типов, как указано в [**PEP 484**](https://python-all.ru/3.5/library/typing.html). Основная поддержка включает типы [`Any`](https://python-all.ru/3.5/library/typing.html#typing.Any), [`Union`](https://python-all.ru/3.5/library/typing.html#typing.Union), [`Tuple`](https://python-all.ru/3.5/library/typing.html#typing.Tuple), [`Callable`](https://python-all.ru/3.5/library/typing.html#typing.Callable), [`TypeVar`](https://python-all.ru/3.5/library/typing.html#typing.TypeVar) и [`Generic`](https://python-all.ru/3.5/library/typing.html#typing.Generic). Полную спецификацию см. в [**PEP 484**](https://python-all.ru/3.5/library/typing.html). Упрощённое введение в подсказки типов см. в [**PEP 483**](https://python-all.ru/3.5/library/typing.html).

Функция ниже принимает и возвращает строку и аннотирована следующим образом:

```python
def greeting(name: str) -> str:
    return 'Hello ' + name
```

В функции `greeting` аргумент `name` ожидается типа [`str`](https://python-all.ru/3.5/library/stdtypes.html#str), а возвращаемый тип – [`str`](https://python-all.ru/3.5/library/stdtypes.html#str). Подтипы допускаются в качестве аргументов.

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

Псевдоним типа определяется присваиванием типа псевдониму. В этом примере `Vector` и `List[float]` будут рассматриваться как взаимозаменяемые синонимы:

```python
from typing import List
Vector = List[float]

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

# Проходит проверку типов; список чисел с плавающей запятой считается Vector.
new_vector = scale(2.0, [1.0, -4.2, 5.4])
```

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

```python
from typing import Dict, Tuple, List

ConnectionOptions = Dict[str, str]
Address = Tuple[str, int]
Server = Tuple[Address, ConnectionOptions]

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

# Статическая проверка типов будет считать предыдущую сигнатуру типа как
# полностью эквивалентную этой.
def broadcast_message(
        message: str,
        servers: List[Tuple[Tuple[str, int], Dict[str, str]]]) -> None:
    ...
```

Обратите внимание, что `None` как аннотация типа является особым случаем и заменяется на `type(None)`.

## 26.1.2. NewType

Для создания отдельных типов используется вспомогательная функция [`NewType()`](https://python-all.ru/3.5/library/typing.html#typing.NewType):

```python
from typing import NewType

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

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

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

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

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

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

```python
# 'output' имеет тип 'int', а не 'UserId'
output = UserId(23413) + UserId(54341)
```

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

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

Это также означает, что невозможно создать подтип `Derived`, поскольку во время выполнения это функция идентичности, а не реальный тип. Аналогично, нельзя создать другой [`NewType()`](https://python-all.ru/3.5/library/typing.html#typing.NewType) на основе типа `Derived`:

```python
from typing import NewType

UserId = NewType('UserId', int)

# Завершается ошибкой во время выполнения и не проходит проверку типов.
class AdminUserId(UserId): pass

# Также не проверяет типы
ProUserId = NewType('ProUserId', UserId)
```

Подробнее см. [**PEP 484**](https://python-all.ru/3.5/library/typing.html).

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

## 26.1.3. Callable

Фреймворки, ожидающие функции обратного вызова с определённой сигнатурой, могут быть аннотированы с помощью `Callable[[Arg1Type, Arg2Type], ReturnType]`.

Например:

```python
from typing import Callable

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

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

Можно объявить возвращаемый тип вызываемого объекта, не указывая сигнатуру вызова, заменив список аргументов многоточием в аннотации типа: `Callable[..., ReturnType]`.

## 26.1.4. Generics

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

```python
from typing import Mapping, Sequence

def notify_by_email(employees: Sequence[Employee],
                    overrides: Mapping[str, str]) -> None: ...
```

Обобщённые типы можно параметризовать с помощью новой фабрики, доступной в typing, называемой [`TypeVar`](https://python-all.ru/3.5/library/typing.html#typing.TypeVar).

```python
from typing import Sequence, TypeVar

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

def first(l: Sequence[T]) -> T:   # Обобщённая функция
    return l[0]
```

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

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

```python
from typing import TypeVar, Generic
from logging import Logger

T = TypeVar('T')

class LoggedVar(Generic[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)
```

`Generic[T]` в качестве базового класса определяет, что класс `LoggedVar` принимает один параметр типа `T`. Это также делает `T` допустимым типом внутри тела класса.

Базовый класс [`Generic`](https://python-all.ru/3.5/library/typing.html#typing.Generic) использует метакласс, который определяет [`__getitem__()`](https://python-all.ru/3.5/reference/datamodel.html#object.__getitem__) так, чтобы `LoggedVar[t]` был допустимым в качестве типа:

```python
from typing import Iterable

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

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

```python
from typing import TypeVar, Generic
...

T = TypeVar('T')
S = TypeVar('S', int, str)

class StrangePair(Generic[T, S]):
    ...
```

Каждый аргумент-переменная типа для [`Generic`](https://python-all.ru/3.5/library/typing.html#typing.Generic) должен быть уникальным. Поэтому такой код некорректен:

```python
from typing import TypeVar, Generic
...

T = TypeVar('T')

class Pair(Generic[T, T]):   # НЕДОПУСТИМО
    ...
```

Можно использовать множественное наследование с [`Generic`](https://python-all.ru/3.5/library/typing.html#typing.Generic):

```python
from typing import TypeVar, Generic, Sized

T = TypeVar('T')

class LinkedList(Sized, Generic[T]):
    ...
```

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

```python
from typing import TypeVar, Mapping

T = TypeVar('T')

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

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

Использование обобщённого класса без указания параметров типа подразумевает [`Any`](https://python-all.ru/3.5/library/typing.html#typing.Any) для каждой позиции. В следующем примере `MyIterable` не является обобщённым, но неявно наследуется от `Iterable[Any]`:

```python
from typing import Iterable

class MyIterable(Iterable): # То же, что и Iterable[Any].
```

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

```python
from typing import TypeVar, Iterable, Tuple, Union
S = TypeVar('S')
Response = Union[Iterable[S], int]

# Тип возврата здесь такой же, как Union[Iterable[str], int]
def response(query: str) -> Response[str]:
    ...

T = TypeVar('T', int, float, complex)
Vec = Iterable[Tuple[T, T]]

def inproduct(v: Vec[T]) -> T: # То же, что Iterable[Tuple[T, T]]
    return sum(x*y for x, y in v)
```

Метакласс, используемый [`Generic`](https://python-all.ru/3.5/library/typing.html#typing.Generic), является подклассом [`abc.ABCMeta`](https://python-all.ru/3.5/library/abc.html#abc.ABCMeta). Обобщённый класс может быть ABC, если содержит абстрактные методы или свойства, и обобщённые классы также могут иметь ABC в качестве базовых классов без конфликта метаклассов. Обобщённые метаклассы не поддерживаются. Результат параметризации дженериков кэшируется, а большинство типов в модуле typing являются хэшируемыми и сравнимыми на равенство.

## 26.1.6. Тип [`Any`](https://python-all.ru/3.5/library/typing.html#typing.Any)

Особым видом типа является [`Any`](https://python-all.ru/3.5/library/typing.html#typing.Any). Статический проверяющий типов будет считать каждый тип совместимым с [`Any`](https://python-all.ru/3.5/library/typing.html#typing.Any), а [`Any`](https://python-all.ru/3.5/library/typing.html#typing.Any) – совместимым с каждым типом.

Это означает, что над значением типа [`Any`](https://python-all.ru/3.5/library/typing.html#typing.Any) можно выполнять любые операции или вызовы методов и присваивать его любой переменной:

```python
from typing import Any

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

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

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

Обратите внимание, что никакая проверка типов не выполняется при присваивании значения типа [`Any`](https://python-all.ru/3.5/library/typing.html#typing.Any) более точному типу. Например, статический проверяющий типы не сообщил об ошибке при присваивании `a` переменной `s`, хотя `s` был объявлен как тип [`str`](https://python-all.ru/3.5/library/stdtypes.html#str) и получает значение [`int`](https://python-all.ru/3.5/library/functions.html#int) во время выполнения!

Кроме того, все функции без указания типа возврата или типов параметров по умолчанию неявно используют [`Any`](https://python-all.ru/3.5/library/typing.html#typing.Any):

```python
def legacy_parser(text):
    ...
    return data

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

Такое поведение позволяет использовать [`Any`](https://python-all.ru/3.5/library/typing.html#typing.Any) в качестве *запасного выхода*, когда нужно смешивать динамически и статически типизированный код.

Сравните поведение [`Any`](https://python-all.ru/3.5/library/typing.html#typing.Any) с поведением [`object`](https://python-all.ru/3.5/library/functions.html#object). Как и [`Any`](https://python-all.ru/3.5/library/typing.html#typing.Any), каждый тип является подтипом [`object`](https://python-all.ru/3.5/library/functions.html#object). Однако, в отличие от [`Any`](https://python-all.ru/3.5/library/typing.html#typing.Any), обратное неверно: [`object`](https://python-all.ru/3.5/library/functions.html#object) *не* является подтипом любого другого типа.

Это означает, что когда тип значения – [`object`](https://python-all.ru/3.5/library/functions.html#object), проверяющий типы будет отклонять почти все операции над ним, а присваивание его переменной (или использование в качестве возвращаемого значения) более специализированного типа является ошибкой типа. Например:

```python
def hash_a(item: object) -> int:
    # Завершается ошибкой; у объекта нет метода 'magic'.
    item.magic()
    ...

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

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

# Проходит проверку типов, так как Any совместим со всеми типами.
hash_b(42)
hash_b("foo")
```

Используйте [`object`](https://python-all.ru/3.5/library/functions.html#object), чтобы указать, что значение может быть любого типа в типобезопасной манере. Используйте [`Any`](https://python-all.ru/3.5/library/typing.html#typing.Any), чтобы указать, что значение динамически типизировано.

## 26.1.7. Классы, функции и декораторы

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

#### `class typing.TypeVar`

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

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

```python
T = TypeVar('T')  # Может быть чем угодно
A = TypeVar('A', str, bytes)  # Должно быть str или bytes
```

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

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

def longest(x: A, y: A) -> A:
    """Возвращает самую длинную из двух строк."""
    return x if len(x) >= len(y) else y
```

Сигнатура последнего примера по сути является перегрузкой `(str, str) -> str` и `(bytes, bytes) -> bytes`. Также обратите внимание, что если аргументы являются экземплярами какого-либо подкласса [`str`](https://python-all.ru/3.5/library/stdtypes.html#str), возвращаемый тип остаётся простым [`str`](https://python-all.ru/3.5/library/stdtypes.html#str).

Во время выполнения `isinstance(x, T)` вызовет [`TypeError`](https://python-all.ru/3.5/library/exceptions.html#TypeError). В общем, [`isinstance()`](https://python-all.ru/3.5/library/functions.html#isinstance) и [`issubclass()`](https://python-all.ru/3.5/library/functions.html#issubclass) не должны использоваться с типами.

Переменные типа могут быть помечены как ковариантные или контравариантные путём передачи `covariant=True` или `contravariant=True`. См. [**PEP 484**](https://python-all.ru/3.5/library/typing.html) для подробностей. По умолчанию переменные типа инвариантны. В качестве альтернативы, переменная типа может указывать верхнюю границу с помощью `bound=<type>`. Это означает, что фактический тип, подставленный (явно или неявно) для переменной типа, должен быть подклассом граничного типа, см. [**PEP 484**](https://python-all.ru/3.5/library/typing.html).

#### `class typing.Generic`

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

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

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

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

```python
X = TypeVar('X')
Y = TypeVar('Y')

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

#### `class typing.Type(Generic[CT_co])`

Переменная, аннотированная `C`, может принимать значение типа `C`. Напротив, переменная, аннотированная `Type[C]`, может принимать значения, которые сами являются классами – а именно, она принимает *объект класса* `C`. Например:

```python
a = 3         # Имеет тип 'int'
b = int       # Имеет тип 'Type[int]'
c = type(a)   # Также имеет тип 'Type[int]'
```

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

```python
class User: ...
class BasicUser(User): ...
class ProUser(User): ...
class TeamUser(User): ...

# Принимает User, BasicUser, ProUser, TeamUser, ...
def make_new_user(user_class: Type[User]) -> User:
    # ...
    return user_class()
```

Тот факт, что `Type[C]` ковариантен, подразумевает, что все подклассы `C` должны реализовывать те же сигнатуры конструктора и методов класса, что и `C`. Средство проверки типов должно отмечать нарушения этого, но также должно разрешать вызовы конструкторов в подклассах, которые соответствуют вызовам конструктора в указанном базовом классе. То, как средство проверки типов должно обрабатывать этот конкретный случай, может измениться в будущих версиях [**PEP 484**](https://python-all.ru/3.5/library/typing.html).

Единственные допустимые параметры для [`Type`](https://python-all.ru/3.5/library/typing.html#typing.Type) – это классы, объединения классов и [`Any`](https://python-all.ru/3.5/library/typing.html#typing.Any). Например:

```python
def new_non_team_user(user_class: Type[Union[BaseUser, ProUser]]): ...
```

`Type[Any]` эквивалентен `Type`, который в свою очередь эквивалентен `type`, корню метаклассовой иерархии Python.

#### `class typing.Iterable(Generic[T_co])`

Обобщённая версия [`collections.abc.Iterable`](https://python-all.ru/3.5/library/collections.abc.html#collections.abc.Iterable).

#### `class typing.Iterator(Iterable[T_co])`

Обобщённая версия [`collections.abc.Iterator`](https://python-all.ru/3.5/library/collections.abc.html#collections.abc.Iterator).

#### `class typing.Reversible(Iterable[T_co])`

Обобщённая версия `collections.abc.Reversible`.

#### `class typing.SupportsInt`

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

#### `class typing.SupportsFloat`

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

#### `class typing.SupportsAbs`

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

#### `class typing.SupportsRound`

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

#### `class typing.Container(Generic[T_co])`

Обобщённая версия [`collections.abc.Container`](https://python-all.ru/3.5/library/collections.abc.html#collections.abc.Container).

#### `class typing.Hashable`

Псевдоним для [`collections.abc.Hashable`](https://python-all.ru/3.5/library/collections.abc.html#collections.abc.Hashable)

#### `class typing.Sized`

Псевдоним для [`collections.abc.Sized`](https://python-all.ru/3.5/library/collections.abc.html#collections.abc.Sized)

#### `class typing.AbstractSet(Sized, Iterable[T_co], Container[T_co])`

Обобщённая версия [`collections.abc.Set`](https://python-all.ru/3.5/library/collections.abc.html#collections.abc.Set).

#### `class typing.MutableSet(AbstractSet[T])`

Обобщённая версия [`collections.abc.MutableSet`](https://python-all.ru/3.5/library/collections.abc.html#collections.abc.MutableSet).

#### `class typing.Mapping(Sized, Iterable[KT], Container[KT], Generic[VT_co])`

Обобщённая версия [`collections.abc.Mapping`](https://python-all.ru/3.5/library/collections.abc.html#collections.abc.Mapping).

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

Обобщённая версия [`collections.abc.MutableMapping`](https://python-all.ru/3.5/library/collections.abc.html#collections.abc.MutableMapping).

#### `class typing.Sequence(Sized, Iterable[T_co], Container[T_co])`

Обобщённая версия [`collections.abc.Sequence`](https://python-all.ru/3.5/library/collections.abc.html#collections.abc.Sequence).

#### `class typing.MutableSequence(Sequence[T])`

Обобщённая версия [`collections.abc.MutableSequence`](https://python-all.ru/3.5/library/collections.abc.html#collections.abc.MutableSequence).

#### `class typing.ByteString(Sequence[int])`

Обобщённая версия [`collections.abc.ByteString`](https://python-all.ru/3.5/library/collections.abc.html#collections.abc.ByteString).

Этот тип представляет типы [`bytes`](https://python-all.ru/3.5/library/functions.html#bytes), [`bytearray`](https://python-all.ru/3.5/library/functions.html#bytearray) и [`memoryview`](https://python-all.ru/3.5/library/stdtypes.html#memoryview).

В качестве сокращения для этого типа [`bytes`](https://python-all.ru/3.5/library/functions.html#bytes) можно использовать для аннотации аргументов любого из упомянутых выше типов.

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

Обобщённая версия [`collections.deque`](https://python-all.ru/3.5/library/collections.html#collections.deque).

Новое в версии 3.5.4.

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

Обобщённая версия [`list`](https://python-all.ru/3.5/library/stdtypes.html#list). Полезна для аннотации возвращаемых типов. Для аннотации аргументов предпочтительнее использовать абстрактные типы коллекций, такие как [`Mapping`](https://python-all.ru/3.5/library/typing.html#typing.Mapping), [`Sequence`](https://python-all.ru/3.5/library/typing.html#typing.Sequence) или [`AbstractSet`](https://python-all.ru/3.5/library/typing.html#typing.AbstractSet).

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

```python
T = TypeVar('T', int, float)

def vec2(x: T, y: T) -> List[T]:
    return [x, y]

def keep_positives(vector: Sequence[T]) -> List[T]:
    return [item for item in vector if item > 0]
```

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

Обобщённая версия [`builtins.set`](https://python-all.ru/3.5/library/stdtypes.html#set).

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

Обобщённая версия [`builtins.frozenset`](https://python-all.ru/3.5/library/stdtypes.html#frozenset).

#### `class typing.MappingView(Sized, Iterable[T_co])`

Обобщённая версия [`collections.abc.MappingView`](https://python-all.ru/3.5/library/collections.abc.html#collections.abc.MappingView).

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

Обобщённая версия [`collections.abc.KeysView`](https://python-all.ru/3.5/library/collections.abc.html#collections.abc.KeysView).

#### `class typing.ItemsView(MappingView, Generic[KT_co, VT_co])`

Обобщённая версия [`collections.abc.ItemsView`](https://python-all.ru/3.5/library/collections.abc.html#collections.abc.ItemsView).

#### `class typing.ValuesView(MappingView[VT_co])`

Обобщённая версия [`collections.abc.ValuesView`](https://python-all.ru/3.5/library/collections.abc.html#collections.abc.ValuesView).

#### `class typing.Awaitable(Generic[T_co])`

Обобщённая версия [`collections.abc.Awaitable`](https://python-all.ru/3.5/library/collections.abc.html#collections.abc.Awaitable).

#### `class typing.Coroutine(Awaitable[V_co], Generic[T_co T_contra, V_co])`

Обобщённая версия [`collections.abc.Coroutine`](https://python-all.ru/3.5/library/collections.abc.html#collections.abc.Coroutine). Вариантность и порядок переменных типа соответствуют таковым у [`Generator`](https://python-all.ru/3.5/library/typing.html#typing.Generator), например:

```python
from typing import List, Coroutine
c = None # type: Coroutine[List[str], str, int]
...
x = c.send('hi') # type: List[str]
async def bar() -> None:
    x = await c # type: int
```

#### `class typing.AsyncIterable(Generic[T_co])`

Обобщённая версия [`collections.abc.AsyncIterable`](https://python-all.ru/3.5/library/collections.abc.html#collections.abc.AsyncIterable).

#### `class typing.AsyncIterator(AsyncIterable[T_co])`

Обобщённая версия [`collections.abc.AsyncIterator`](https://python-all.ru/3.5/library/collections.abc.html#collections.abc.AsyncIterator).

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

Обобщённая версия [`dict`](https://python-all.ru/3.5/library/stdtypes.html#dict). Использование этого типа выглядит следующим образом:

```python
def get_position_in_index(word_list: Dict[str, int], word: str) -> int:
    return word_list[word]
```

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

Обобщённая версия [`collections.defaultdict`](https://python-all.ru/3.5/library/collections.html#collections.defaultdict)

#### `class typing.Generator(Iterator[T_co], Generic[T_co, T_contra, V_co])`

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

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

Обратите внимание: в отличие от многих других обобщённых типов в модуле typing, `SendType` из [`Generator`](https://python-all.ru/3.5/library/typing.html#typing.Generator) ведёт себя контравариантно, а не ковариантно или инвариантно.

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

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

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

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

#### `class typing.AsyncGenerator(AsyncIterator[T_co], Generic[T_co, T_contra])`

Асинхронный генератор можно аннотировать обобщённым типом `AsyncGenerator[YieldType, SendType]`. Например:

```python
async def echo_round() -> AsyncGenerator[int, float]:
    sent = yield 0
    while sent >= 0.0:
        rounded = await round(sent)
        sent = yield rounded
```

В отличие от обычных генераторов, асинхронные генераторы не могут возвращать значение, поэтому параметр типа `ReturnType` отсутствует. Как и в случае с [`Generator`](https://python-all.ru/3.5/library/typing.html#typing.Generator), `SendType` ведёт себя контравариантно.

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

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

В качестве альтернативы аннотируйте генератор как имеющий тип возвращаемого значения либо `AsyncIterable[YieldType]`, либо `AsyncIterator[YieldType]`:

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

Новое в версии 3.5.4.

#### `class typing.Text`

`Text` – это псевдоним для `str`. Он предоставляется для обеспечения совместимости с кодом Python 2: в Python 2 `Text` является псевдонимом для `unicode`.

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

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

#### `class typing.io`

Пространство имён-обёртка для типов потоков ввода-вывода.

Это определяет обобщённый тип `IO[AnyStr]` и псевдонимы `TextIO` и `BinaryIO` для `IO[str]` и `IO[bytes]` соответственно. Они представляют типы потоков ввода-вывода, такие как возвращаемые [`open()`](https://python-all.ru/3.5/library/functions.html#open).

#### `class typing.re`

Пространство имён-обёртка для типов сопоставления с регулярными выражениями.

Это определяет псевдонимы типов `Pattern` и `Match`, которые соответствуют возвращаемым типам из [`re.compile()`](https://python-all.ru/3.5/library/re.html#re.compile) и [`re.match()`](https://python-all.ru/3.5/library/re.html#re.match). Эти типы (и соответствующие функции) являются обобщёнными по `AnyStr` и могут быть конкретизированы записью `Pattern[str]`, `Pattern[bytes]`, `Match[str]` или `Match[bytes]`.

#### `typing.NamedTuple(typename, fields)`

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

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

```python
Employee = typing.NamedTuple('Employee', [('name', str), ('id', int)])
```

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

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

Результирующий класс имеет один дополнительный атрибут: \_field\_types, предоставляющий словарь, сопоставляющий имена полей с типами. (Имена полей находятся в атрибуте \_fields, который является частью API namedtuple.)

#### `typing.NewType(typ)`

Вспомогательная функция для указания статическому анализатору, что тип является отдельным; см. [NewType](https://python-all.ru/3.5/library/typing.html#distinct). Во время выполнения возвращает функцию, которая возвращает свой аргумент. Использование:

```python
UserId = NewType('UserId', int)
first_user = UserId(1)
```

#### `typing.cast(typ, val)`

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

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

#### `typing.get_type_hints(obj[, globals[, locals]])`

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

Это часто совпадает с `obj.__annotations__`. Кроме того, прямые ссылки, закодированные как строковые литералы, обрабатываются путём вычисления их в пространствах имён `globals` и `locals`. При необходимости `Optional[t]` добавляется для аннотаций функций и методов, если задано значение по умолчанию, равное `None`. Для класса `C` возвращается словарь, построенный объединением всех `__annotations__` по `C.__mro__` в обратном порядке.

#### `@typing.overload`

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

```python
@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>
```

См. [**PEP 484**](https://python-all.ru/3.5/library/typing.html) для подробностей и сравнения с другими семантиками типизации.

#### `@typing.no_type_check(arg)`

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

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

Это изменяет функцию(и) на месте.

#### `@typing.no_type_check_decorator(decorator)`

Декоратор, придающий другому декоратору эффект [`no_type_check()`](https://python-all.ru/3.5/library/typing.html#typing.no_type_check).

Он оборачивает декоратор чем-то, что оборачивает декорированную функцию в [`no_type_check()`](https://python-all.ru/3.5/library/typing.html#typing.no_type_check).

#### `typing.Any`

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

- Каждый тип совместим с [`Any`](https://python-all.ru/3.5/library/typing.html#typing.Any).
- [`Any`](https://python-all.ru/3.5/library/typing.html#typing.Any) совместим с каждым типом.

#### `typing.Union`

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

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

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

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

  ```python
  Union[int] == int  # Конструктор на самом деле возвращает int
  ```
- Повторяющиеся аргументы пропускаются, например:

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

  ```python
  Union[int, str] == Union[str, int]
  ```
- Когда присутствуют класс и его подкласс, последний пропускается, например:

  ```python
  Union[int, object] == object
  ```
- Нельзя создавать подкласс или экземпляр объединения.
- Нельзя записать `Union[X][Y]`.
- Можно использовать `Optional[X]` как сокращение для `Union[X, None]`.

#### `typing.Optional`

Тип Optional.

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

Обратите внимание, что это не то же самое, что необязательный аргумент, который имеет значение по умолчанию. Необязательный аргумент со значением по умолчанию не обязан использовать квалификатор `Optional` в аннотации типа (хотя он выводится, если значение по умолчанию – `None`). Обязательный аргумент может по-прежнему иметь тип `Optional`, если допускается явное значение `None`.

#### `typing.Tuple`

Тип кортежа; `Tuple[X, Y]` – это тип кортежа из двух элементов с первым элементом типа X и вторым типа Y.

Пример: `Tuple[T1, T2]` – это кортеж из двух элементов, соответствующих переменным типа T1 и T2. `Tuple[int, float, str]` – это кортеж из int, float и строки.

Чтобы задать кортеж переменной длины из однотипных элементов, используйте литеральное многоточие, например `Tuple[int, ...]`. Простой [`Tuple`](https://python-all.ru/3.5/library/typing.html#typing.Tuple) эквивалентен `Tuple[Any, ...]`, а тот, в свою очередь, [`tuple`](https://python-all.ru/3.5/library/stdtypes.html#tuple).

#### `typing.Callable`

Тип Callable; `Callable[[int], str]` – это функция вида (int) -\> str.

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

Нет синтаксиса для указания необязательных или именованных аргументов; такие типы функций редко используются в качестве типов колбэков. `Callable[..., ReturnType]` (буквальное многоточие) можно использовать для аннотации вызываемого объекта, принимающего любое количество аргументов и возвращающего `ReturnType`. Обычное [`Callable`](https://python-all.ru/3.5/library/typing.html#typing.Callable) эквивалентно `Callable[..., Any]`, а в свою очередь – [`collections.abc.Callable`](https://python-all.ru/3.5/library/collections.abc.html#collections.abc.Callable).

#### `typing.ClassVar`

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

Как представлено в [**PEP 526**](https://python-all.ru/3.5/library/typing.html), аннотация переменной, обёрнутая в ClassVar, указывает, что данный атрибут предназначен для использования в качестве переменной класса и не должен устанавливаться на экземплярах этого класса. Использование:

```python
class Starship:
    stats = {}  # type: ClassVar[Dict[str, int]] # class variable
    damage = 10 # type: int                      # instance variable
```

[`ClassVar`](https://python-all.ru/3.5/library/typing.html#typing.ClassVar) принимает только типы и не может быть дополнительно индексирован.

[`ClassVar`](https://python-all.ru/3.5/library/typing.html#typing.ClassVar) сам по себе не является классом, и его не следует использовать с [`isinstance()`](https://python-all.ru/3.5/library/functions.html#isinstance) или [`issubclass()`](https://python-all.ru/3.5/library/functions.html#issubclass). Обратите внимание, что [`ClassVar`](https://python-all.ru/3.5/library/typing.html#typing.ClassVar) не изменяет поведение Python во время выполнения; он может использоваться сторонними проверяющими типы, так что следующий код может помечаться ими как ошибочный:

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

Новое в версии 3.5.3.

#### `typing.AnyStr`

`AnyStr` – это переменная типа, определённая как `AnyStr = TypeVar('AnyStr', str, bytes)`.

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

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

concat(u"foo", u"bar")  # Ок, результат имеет тип 'unicode'
concat(b"foo", b"bar")  # Ок, результат имеет тип 'bytes'
concat(u"foo", b"bar")  # Ошибка, нельзя смешивать unicode и bytes
```

#### `typing.TYPE_CHECKING`

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

```python
if TYPE_CHECKING:
    import expensive_mod

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

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