Why are single type constraints disallowed in Python?
Suppose you want to constrain a type variable to implement a certain interface. You might write something like so:
from typing import TypeVar, Callable
T = TypeVar('T', Callable)
class Foo(Generic[T]):
...
>> TypeError: A single constraint is not allowed
Why is Python unhappy about this use of type constraints? PEP 484 and the Python source code are unhelpful in this regard.
Note: in my particular case I am interested in constraining a type variable to implement an abstract base class, but the principle is the same.
Solution 1:
You’re looking for bound
:
T = TypeVar('T', bound=Callable)
From the docs:
a type variable may specify an upper bound using
bound=<type>
. This means that an actual type substituted (explicitly or implicitly) for the type variable must be a subclass of the boundary type, see PEP 484.
TypeVar(name, *args)
means that the type has to be one of args
, so all instances of T
would just be replaceable by Callable
if T = TypeVar('T', Callable)
were allowed.
You should be able to see the difference here (though I didn’t actually try it, heh):
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) # doesn’t typecheck because f.value is only a Callable