Open dhruvmanila opened 1 month ago
Regarding "Use the unpacking logic in other places where it's relevant like" task, I think the challenge here would be to implement the logic to "combine" union types into a single type. For example, in a for
loop like:
for (x, y) in ((1, 2), (3, 4), (5, 6)): ...
The inferred type for the iterable would be:
tuple[Literal[1], Literal[2]] | tuple[Literal[3], Literal[4]] | tuple[Literal[5], Literal[6]]
But, we should combine it to:
tuple[int, int]
# or
tuple[Literal[1, 3, 5], Literal[2, 4, 6]]
Or, another example where the types are "mixed":
for (x, y) in ((1, 2), ("a", "b")): ...
We should combine it to:
tuple[int | str, int | str]
# or
tuple[Literal[1, "a"], Literal[2, "b"]]
Another example:
for (x, y) in ((1, 2), ("a", 3)): ...
where,
tuple[int | str, int]
# or
tuple[Literal[1, "a"], Literal[2, 3]]
As https://github.com/astral-sh/ruff/pull/13316 is merged, there are some follow-up work that needs to be done. The following is a list in the order of priority where the highest priority work is on the top:
(a, b) = (1, 2)
, as the inference runs for each symbol, if there are any diagnostics that's raised during that part (like "too many values to unpack"), then there will be multiple diagnostics added to the builder one for each symbol. Refer https://github.com/astral-sh/ruff/pull/13316#discussion_r1800219731for
loops e.g.,for (x, y) in ((1, 2), (3, 4)): ...
with
statements e.g.,with (item1, item2) as (x, y): ...
[_ for (x, y) in [(1, 2), (3, 4)]]
(a, *b, c) = (1, 2, 3, 4)
, theLiteral[2]
andLiteral[3]
type should be combined intolist[int]
to be assigned to*b
. (Requires generic support over list) https://github.com/astral-sh/ruff/blob/c6b311c54643c039d793fb836caf94d22f03cbb4/crates/red_knot_python_semantic/src/types/infer.rs#L1248-L1251