I recently discovered that MyPy supports a generic callable type shorthand that Pyre does not, namely things of the form ``` from typing import Callable, TypeVar T = TypeVar("T") def produce_no_op_decorator() -> Callable[[T], T]:... ``` MyPy interprets this as being of type `Callable[[], Callable<T>[[T], T]]` (mod https://github.com/python/mypy/issues/3924), while Pyre interprets it as being of type `Callable<T>[[], Callable[[T], T]]`, which we reject as being invalid. Pyre interprets all free type variables in a def or class as being in the scope of that define/class. MyPy also does this in most circumstances with Callable[[T], T], as both checkers have identical interpretations of ``` T = TypeVar("T") def f(x: T) -> Callable[[T], T]: ... # def <T> (T) -> Callable[[T], T] # and def f(f: Callable[[T], T]) -> T: ... # def <T> (Callable[[T], T]) -> T #and def i() -> Tuple[Callable[[T], T], T]: ... # def <T> () -> Tuple[Callable[[T], T], T]: ... # and class Child(Base[Callable[[T], T]]): ... # class <T> Child(Base[Callable[[T], T]]) ``` Pyre and MyPy only differ here in that MyPy introduces a unique special case that alters the behavior for free variables: * inside a Callable type * in the return type of a def * not present in any parameter of the def * not present anywhere else in the return type that isn't also inside of a Callable type. I can definitely see how this special case is helpful in making definitions for decorator factories more compact, but for us the inconsistency of this behavior from a user's perspective outweighs the concision. With all that being said, given that the semantics of this are unspecified in any PEPs, I think it's fine for there to be a divergence in interpretation here. However, there are instances of this pattern in typeshed, which have been leading to strange behavior in Pyre. Luckily, both MyPy and Pyre have a spelling of `produce_no_op_decorator` that they both agree on, and is mostly codified by a PEP: ``` from typing import Callable, TypeVar, Protocol T = TypeVar("T") class IdentityFunction(Protocol): def __call__(self, __x: T) -> T: ... def produce_no_op_decorator() -> IdentityFunction... ``` What are people's thoughts on modifying typeshed (like in https://github.com/python/typeshed/pull/4045) to change these instances to the commonly accepted spelling?