Почему ограничения на один тип запрещены в Python?

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

from typing import TypeVar, Callable

T = TypeVar('T', Callable)

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

>> TypeError: A single constraint is not allowed

Почему Python недоволен этим использованием ограничений типа? PEP 484 и исходный код Python в этом не помогают.

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

Ответ 1

Вы ищете bound:

T = TypeVar('T', bound=Callable)

Из документов:

переменная типа может указывать верхнюю границу, используя bound=<type>. Это означает, что фактический тип, замененный (явно или неявно) переменной типа, должен быть подклассом типа границы, см. PEP 484.

TypeVar(name, *args) означает, что тип должен быть одним из args, поэтому все экземпляры T можно было бы просто заменить на Callable, если бы T = TypeVar('T', Callable) был разрешен.

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

from typing import Generic, TypeVar, Callable

T = TypeVar('T', Callable, bool)

class Foo(Generic[T]):
    value: T

    def __init__(self, value: T) -> None:
        self.value = value

class Bar:
    baz = 5

    def __call__(self):
        pass

f = Foo(Bar())
print(f.value.baz)  # doesnt typecheck because f.value is only a Callable

Ответ 2

Ограничение User_ID должно быть int

from typing import NewType
UserId = NewType('UserId', int)
some_id = UserId(524313)