Hi typing-sig,
This question has come up a few times from pytype's users: How do you write
a generic function that only takes arguments that are the same subclass of
a particular base class?
That is, if you have a function like:
def do_stuff(x, y): ...
If you want it to take two args of the same type, but that type is
otherwise not constrained, use a regular TypeVar:
T = TypeVar("T")
def do_stuff(x: T, y: T): ...
If you want do_stuff to only accept args of certain types, you can limit
the TypeVar to those types:
T = TypeVar("T", int, str)
def do_stuff(x: T, y: T): ...
do_stuff(<int>, <int>) or do_stuff(<str>, <str>) are the only valid calls.
This works if the constraining types are known ahead of time.
If you want do_stuff to only accept args of a particular base type, use
bound:
T = TypeVar("T", bound=Base)
def do_stuff(x: T, y: T): ...
If A and B are subclasses of Base, then do_stuff(A(), A()), do_stuff(A(),
B()) and do_stuff(A(), Base()) are all legal.
As far as I can tell, there is no way to express that do_stuff(A(), A())
and do_stuff(B(), B()) are legal while do_stuff(A(), B()) and do_stuff(A(),
Base()) are illegal, for all subclasses of Base.
Am I missing something?
(Pytype does accept one way to do it, though this is unintended:
T = TypeVar("T", Base, Base)
def do_stuff(x: T, y: T): ...
mypy treats this the same as the bound=Base case, but pytype will complain
about do_stuff(A(), B()). PEP 484 doesn't have anything to say about this
case, as far as I know.)
-- Teddy