ruff
8a98d888 - [red-knot] Add diagnostic for invalid unpacking (#15086)

Commit
258 days ago
[red-knot] Add diagnostic for invalid unpacking (#15086) ## Summary Part of #13773 This PR adds diagnostics when there is a length mismatch during unpacking between the number of target expressions and the number of types for the unpack value expression. There are 3 cases of diagnostics here where the first two occurs when there isn't a starred expression and the last one occurs when there's a starred expression: 1. Number of target expressions is **less** than the number of types that needs to be unpacked 2. Number of target expressions is **greater** then the number of types that needs to be unpacked 3. When there's a starred expression as one of the target expression and the number of target expressions is greater than the number of types Examples for all each of the above cases: ```py # red-knot: Too many values to unpack (expected 2, got 3) [lint:invalid-assignment] a, b = (1, 2, 3) # red-knot: Not enough values to unpack (expected 2, got 1) [lint:invalid-assignment] a, b = (1,) # red-knot: Not enough values to unpack (expected 3 or more, got 2) [lint:invalid-assignment] a, *b, c, d = (1, 2) ``` The (3) case is a bit special because it uses a distinct wording "expected n or more" instead of "expected n" because of the starred expression. ### Location The diagnostic location is the target expression that's being unpacked. For nested targets, the location will be the nested expression. For example: ```py (a, (b, c), d) = (1, (2, 3, 4), 5) # ^^^^^^ # red-knot: Too many values to unpack (expected 2, got 3) [lint:invalid-assignment] ``` For future improvements, it would be useful to show the context for why this unpacking failed. For example, for why the expected number of targets is `n`, we can highlight the relevant elements for the value expression. In the **ecosystem**, **Pyright** uses the target expressions for location while **mypy** uses the value expression for the location. For example: ```py if 1: # mypy: Too many values to unpack (2 expected, 3 provided) [misc] # vvvvvvvvv a, b = (1, 2, 3) # ^^^^ # Pyright: Expression with type "tuple[Literal[1], Literal[2], Literal[3]]" cannot be assigned to target tuple #   Type "tuple[Literal[1], Literal[2], Literal[3]]" is incompatible with target tuple #     Tuple size mismatch; expected 2 but received 3 [reportAssignmentType] # red-knot: Too many values to unpack (expected 2, got 3) [lint:invalid-assignment] ``` ## Test Plan Update existing test cases TODO with the error directives.
Author
Parents
Loading