pyrefly
pyrefly copied to clipboard
Validate typevar instantiation against constraints and bounds
Minimal repro:
def foo[T: str](x: T) -> T: ...
def bar[T: (str, bytes)](x: T) -> T: ...
def test() -> None:
foo(42)
bar(42)
Expected: Both foo(42) and bar(42) should be invalid -- the callees have already declared that they only accept bytes/str.
Actual: No type error
Ah, this was in the diff I had a few weeks back that got reverted because of deadlock
Some more tests -- we need to check on instantiation too, not just type application.
from typing import *
@overload
def foo[T: int](x: T) -> T: ...
@overload
def foo(x: object) -> object: ...
def foo(x: object) -> object:
return x
assert_type(foo(0), int)
assert_type(foo(True), bool)
assert_type(foo("foo"), object) # should pass
def bar[T: int](x: T) -> T:
return x
bar("foo") # should error
class C[T: int]:
pass
x: C[str] = C() # should error
Another fun(?) case -- Variable::Contained should remember bounds.
class C[T: int]:
def __init__(self) -> None: ...
def set(self, x: T) -> None: ...
c = C() # C[X] s.t. X <: int
c.set("foo") # str </: int, but no error