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