-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[red-knot] Follow-up from unpacked tuple assignment work #13773
Comments
## Summary This PR adds a new salsa query and an ingredient to resolve all the variables involved in an unpacking assignment like `(a, b) = (1, 2)` at once. Previously, we'd recursively try to match the correct type for each definition individually which will result in creating duplicate diagnostics. This PR still doesn't solve the duplicate diagnostics issue because that requires a different solution like using salsa accumulator or de-duplicating the diagnostics manually. Related: #13773 ## Test Plan Make sure that all unpack assignment test cases pass, there are no panics in the corpus tests. ## Todo - [x] Look at the performance regression
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 (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]] |
Actually, my previous comment isn't exactly correct. We actually need to add support for union types when unpacking rather than combining the types. For example, if the type is cc @carljm as we talked about this in our 1:1 yesterday. |
## Summary Refer: #13773 (comment) This PR adds support for unpacking union types. Unpacking a union type requires us to first distribute the types for all the targets that are involved in an unpacking. For example, if there are two targets and a union type that needs to be unpacked, each target will get a type from each element in the union type. For example, if the type is `tuple[int, int] | tuple[int, str]` and the target has two elements `(a, b)`, then * The type of `a` will be a union of `int` and `int` which are at index 0 in the first and second tuple respectively which resolves to an `int`. * Similarly, the type of `b` will be a union of `int` and `str` which are at index 1 in the first and second tuple respectively which will be `int | str`. ### Refactors There are couple of refactors that are added in this PR: * Add a `debug_assertion` to validate that the unpack target is a list or a tuple * Add a separate method to handle starred expression ## Test Plan Update `unpacking.md` with additional test cases that uses union types. This is done using parameter type hints style.
As #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 [red-knot] Infer target types for unpacked tuple assignment #13316 (comment)for
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)ruff/crates/red_knot_python_semantic/src/types/infer.rs
Lines 1248 to 1251 in c6b311c
The text was updated successfully, but these errors were encountered: