Summary
ty appears to incorrectly widen independent generic parameters when a function accepts a Callable with a union-typed parameter, like
def foo[T1, T2](t1: T1, t2: T2, f: Callable[[T1 | T2], None]): ...
Both T1 and T2 are widened to T1 | T2, apparently caused by the presence of the Callable. For reference, this doesn't happen if the third argument is a simple T1 | T2 value, or a list[T1 | T2].
Reproducer
In the example below, T1 and T2 should cleanly map to X1 and X2, but ty infers both as X1 | X2:
import typing
from collections.abc import Callable
class X1: ...
class X2: ...
def foo[T1, T2](
t1: T1,
t2: T2,
f: Callable[[T1 | T2], None],
) -> tuple[T1, T2]:
f(t1), f(t2)
return t1, t2
def fx(_: X1 | X2) -> None: ...
result = foo(X1(), X2(), fx)
typing.assert_type(result, tuple[X1, X2])
# ty 0.0.27
# error[type-assertion-failure]: Argument does not have asserted type `tuple[X1, X2]`
# Inferred type is `tuple[X1 | X2, X2 | X1]`
Maybe related
This may be related to #2799?
Version
ty 0.0.27
Summary
tyappears to incorrectly widen independent generic parameters when a function accepts aCallablewith a union-typed parameter, likeBoth
T1andT2are widened toT1 | T2, apparently caused by the presence of theCallable. For reference, this doesn't happen if the third argument is a simpleT1 | T2value, or alist[T1 | T2].Reproducer
In the example below,
T1andT2should cleanly map toX1andX2, buttyinfers both asX1 | X2:Maybe related
This may be related to #2799?
Version
ty 0.0.27