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.
It is a type variable. Type variables exist primarily for the benefit of static type checkers. They serve as the parameters for generic types as well as for generic function definitions.
Python is a dynamically typed language. This means that the Python interpreter does type checking only as code runs, and that the type of a variable is allowed to change over its lifetime.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With