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