-
Couldn't load subscription status.
- Fork 165
Description
Describe the Bug
This bug is identical to this bug in Pyright: microsoft/pyright#11016
Code sample:
from collections.abc import Callable
def get_identity[T](name: str) -> Callable[[T], tuple[T, T]]:
tees: list[T] = []
def f(x: T) -> tuple[T, T]:
if tees:
last = tees.pop()
else:
last = x
tees.append(x)
return x, last
f.__name__ = name
return f
identity = get_identity("banana")
a0, b0 = identity(42)
# a0, b0 are both int
a1, b1 = identity("aaa")
# a1, b1 are both str for pyrefly
# but of course b1 is 42 at runtimeUsing a type variable scoped to get_identity to denote that it returns a generic function is called "rescoping" and it's not allowed by the typing spec: discourse link, instead you're supposed to define a protocol with a generic __call__ method. It is supported by mypy and pyright for compatibility reasons.
In this case, pyrefly seems to allow the use of the T type variable (which is supposed to only exist inside the returned function) inside the enclosing functions, which is not correct. mypy correctly complains at the tees: list[T] = [] line that T is not defined.