TGViewer
Находки в опенсорсе Находки в опенсорсе @opensource_findings · 12.6K subscribers
Post #860 7.42K
type alias'ы в пятницу вечером

История одного PR: https://github.com/python/cpython/pull/124795

Как вы знаете, в PEP695 (https://peps.python.org/pep-0695/) были добавлены новые тайпалиасы, которые работают поверх нового синтаксиса: type ResultE[T] = Result[T, Exception]

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


>>> type A[T, T] = ...
SyntaxError: duplicate type parameter 'T'


- Нельзя использовать литералы вместо имен:


>>> type A[1] = ...
SyntaxError: invalid syntax


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


>>> type A[T=int, S] = ...
SyntaxError: non-default type parameter 'S' follows default type parameter


Сколько на самом деле тайпалиасов?

Однако, все не так просто. Ведь на самом деле синтаксис type просто создает обычный рантайм объект типа typing.TypeAliasType. И его можно создать руками.


>>> type A[T] = list[T]

>>> type(A)
<class 'typing.TypeAliasType'>
>>> A.__type_params__
(T,)
>>> A.__value__
list[T]


Сравните с "ручным" способом (они почти идентичны, кроме ленивости вычисления `list[T]`):


>>> from typing import TypeAliasType, TypeVar
>>> T = TypeVar('T', infer_variance=True)
>>> A = TypeAliasType('A', list[T], type_params=(T,))

>>> type(A)
<class 'typing.TypeAliasType'>
>>> A.__type_params__
(T,)
>>> A.__value__
list[T]


Так вот 🌚️️️️
У меня еще не все. Есть еще один TypeAliasType 😱
В typing_extensions для портирования поддержки библиотеками, кто инспектирует аннотации на 3.11 и ниже.
Вот он: https://github.com/python/typing_extensions/blob/17d3a37635bad3902c4e913a48d969cbebfb08c3/src/typing_extensions.py#L3503

Проблемы в реализации

Пользователь нашел проблему, что при ручном создании TypeAliasType не было никаких проверок. Почему? потому что все проверки были не в самом коде объекта, а на уровне парсера / компилятора. Руками туда можно было отправиль что угодно! И в C версию, и в Python версию.

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


for (Py_ssize_t index = 0; index < length; index++) {
PyObject *type_param = PyTuple_GET_ITEM(type_params, index);
PyObject *dflt = get_type_param_default(ts, type_param);
if (dflt == NULL) {
*err = 1;
return NULL;
}
if (dflt == &_Py_NoDefaultStruct) {
if (default_seen) {
*err = 1;
PyErr_Format(PyExc_TypeError,
"non-default type parameter '%R' "
"follows default type parameter",
type_param);
return NULL;
}
} else {
default_seen = 1;
Py_DECREF(dflt);
}
}


Практическая ценность

Кстати, такие тайпалиасы уже работают! Смотрите на --enable-incomplete-feature=NewGenericSyntax в mypy:


type A[T] = list[T]

def get_first[T](arg: A[T]) -> T:
return arg[0]

reveal_type(get_first([1, 2, 3]))


https://mypy-play.net/?mypy=latest&python=3.12&enable-incomplete-feature=NewGenericSyntax&flags=strict&gist=7b33597fb3f0cb723ac816efc2e2caef

Как вы используете type alias'ы в своем коде?
Какой вид предпочитаете: TypeAlias, TypeAliasType, ключевое слово type?
  • 🤯 28
  • 👍 9
  • 😱 6
  • ❤ 2
More from @opensource_findings
  1. Sep 28, 2026Еще анонсы докладов на бесплатную конференцию 17 октября в НН Регистрация: https://itgorky…
  2. Sep 25, 2026Монадические выражения в Python. Наконец-то! Продолжаем разговор про интересные PEPы. Пого…
  3. Sep 15, 2026PEPы в Python окончательно вышли из-под контроля Давайте посмотрим, что происходит с ПЕПам…
  4. Sep 10, 2026Большая бесплатная конференция в Нижнем Новгороде 17 октября Регистрация: https://itgorky.…
  5. Sep 1, 2026Post #985
  6. Aug 24, 2026JIT могут удалить из CPython! PEP-836: https://peps.python.org/pep-0836 JIT в CPython имее…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →