ty icon indicating copy to clipboard operation
ty copied to clipboard

Use Iterable type context when inferring types inside a literal tuple

Open gpajot opened this issue 4 weeks ago • 3 comments

Summary

This has some similarities with https://github.com/astral-sh/ty/issues/1576 at first glance.

Playground link

It fails in all those circumstances:

  • float is replaced by any union type (float itself is transformed to int | float as per the error message)
  • Iterable is replaced by Sequence (and maybe other collections.abc types?)
  • input value is replaced by set or list
  • dataclass is replaced by either a normal generic class or a generic pydantic model

It does work if we replace Iterable by a concrete container class such as tuple. It also works if replacing the generic data class by a generic built-in type such as list[T].

Thanks for the tremendous work by the way!

Version

ty 0.0.3 (06305f3c0 2025-12-18)

gpajot avatar Dec 18 '25 07:12 gpajot

Thank you for reporting this.

This seems like a problem that is related to invariance and the float special case.

The error goes away if I change v: T to _v: T to make Value covariant in T.

Maybe it's also related to bidirectional type-checking (involving generic protocols), because this works just fine:

def accepts_single_value(value: Value[float]): ...

accepts_single_value(Value(1.))

sharkdp avatar Dec 18 '25 09:12 sharkdp

Right 👍 thanks for the replay, makes sense. Using Final[T] works as well, though specifying the data class as frozen doesn't seem to make it infer the proper variance.

gpajot avatar Dec 18 '25 10:12 gpajot