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?
_______________________________________________
Typing-sig mailing list -- typing-sig@python.org
To unsubscribe send an email to typing-sig-leave@python.org
https://mail.python.org/mailman3/lists/typing-sig.python.org/
Member address: rechen@google.com