pyre-check
pyre-check copied to clipboard
Explicit TypeVars (e.g. `TypeVar("T", int, str)`) can't be satisfied from refinement + new construction
When returning a value that fits within the typevar constraint, the checker returns an Incompatible return type [7]
error. To reproduce:
T = TypeVar("T", int, str)
def fn(value: T) -> T:
if isinstance(value, int):
return int(5)
else:
return str("five")
This raises Incompatible return type [7]: Expected Variable[T <: [int, str]] but got int
and Incompatible return type [7]: Expected Variable[T <: [int, str]] but got str
This works correctly:
def fn(value: T) -> T:
return value
We don't currently support this use of explicit type variables. We already enforce the exterior behavior necessary to make this sound (e.g fn(my_int_subclass) -> int
, not my_int_subclass
), but have not yet implemented the internal logic to accept these cases as demanded by PEP 484.
Doing so would require some fairly significant extensions to our type variable system, and would be something we'd potentially be interested in doing, and would be possible, but I'd imagine it would unfortunately be a while before we'd get around to it.
The current behavior appears to be correct according to PEP 484. The code in the first sample should generate errors.
The problem is that the signature of fn
indicates that it accepts an object that must be a subtype of either int
or str
and return the same type. The body of the function is returning either int
or str
, which are not guaranteed to be the same as the type of the input parameter value
.
The second example is fine because value
is know to be of type T
, so it's fine for it to be used as a return value.