Добавлено в Python 3.12.
Изменено в Python 3.13: добавлена поддержка значений по умолчанию (см. PEP 696).
type_params ::= "[" type_param ("," type_param)* "]"
type_param ::= typevar | typevartuple | paramspec
typevar ::= identifier (":" expression)? ("=" expression)?
typevartuple ::= "*" identifier ("=" expression)?
paramspec ::= "**" identifier ("=" expression)?
Функции (включая сопрограммы), классы и псевдонимы типов могут содержать список типов параметров/аргументов:
def max[T](args: list[T]) -> T: ... async def amax[T](args: list[T]) -> T: ... class Bag[T]: def __iter__(self) -> Iterator[T]: ... def add(self, arg: T) -> None: ... type ListOrSet[T] = list[T] | set[T]
Семантически это указывает на то, что функция, класс или псевдоним типа являются универсальными для типа переменной. Эта информация в основном используется средствами проверки статических типов, и во время выполнения универсальные объекты ведут себя так же, как их неуниверсальные аналоги.
Тип списка параметров/аргументов объявляются в квадратных скобках ([]) сразу после имени функции, класса или псевдонима типа. Типы параметров/аргументов доступны в области универсального объекта, но не где-либо еще. Таким образом, после объявления def func[T](): pass имя T недоступно в области видимости модуля. Ниже семантика универсальных объектов описана более точно. Область действия типов параметров/аргументов моделируется с помощью специальной функции (технической области аннотации), которая завершает создание универсального объекта.
Универсальные функции, классы и псевдонимы типов имеют атрибут __type_params__, в котором перечислены типы параметров/аргументов.
Типы списков параметров/аргументов бывают трех видов:
typing.TypeVar, представленный простым именем (например, T). Семантически это представляет один тип для средства проверки типов.typing.TypeVarTuple, представленный именем с префиксом одной звездочки (например, *Ts). Семантически это означает кортеж любого количества типов.typing.ParamSpec, представленный именем с префиксом двух звездочек (например, **P). Семантически это означает параметры вызываемого объекта.Объявления typing.TypeVar могут определять границы и ограничения с помощью двоеточия (:), за которым следует выражение. Одиночное выражение после двоеточия указывает на границу (например, T: int). Семантически это означает, что typing.TypeVar может представлять только типы, которые являются подтипом этой границы. Кортеж выражений в скобках после двоеточия указывает на набор ограничений (например, T:(str, bytes)). Каждый член кортежа должен быть типом (опять же, это не обязательно во время выполнения). Переменные ограниченного типа могут принимать только один из типов в списке ограничений.
Для typing.TypeVars, объявленного с использованием синтаксиса списка типов, привязка и ограничения не оцениваются при создании универсального объекта, а только тогда, когда к значению осуществляется явный доступ через атрибуты __bound__ и __constraints__. Для этого границы или ограничения оцениваются в отдельной области аннотаций.
typing.TypeVarTuples и typing.ParamSpecs не могут иметь границ или ограничений.
Все три разновидности типов для списка параметров/аргументов также могут иметь значение по умолчанию, которое используется, когда тип параметра/аргумента явно не указан. Это добавляется путем одного знака равенства (=), за которым следует выражение. Подобно границам и ограничениям типа переменных, значение по умолчанию не оценивается при создании объекта, а только при доступе к атрибуту __default__ типа параметра . Для этого значение по умолчанию оценивается в отдельной области аннотации. Если для типа параметра/аргумента не указано значение по умолчанию, то атрибуту __default__ присваивается специальный тип сторожевого typing.NoDefault.
В следующем примере показан полный набор разрешенных объявлений типов параметров:
def overly_generic[ SimpleTypeVar, TypeVarWithDefault = int, TypeVarWithBound: int, TypeVarWithConstraints: (str, bytes), *SimpleTypeVarTuple = (int, float), **SimpleParamSpec = (str, bytearray), ]( a: SimpleTypeVar, b: TypeVarWithDefault, c: TypeVarWithBound, d: Callable[SimpleParamSpec, TypeVarWithConstraints], *e: SimpleTypeVarTuple, ): ...