mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 05:14:52 +00:00
[ty] Match variadic argument to variadic parameter (#20511)
## Summary Closes: https://github.com/astral-sh/ty/issues/1236 This PR fixes a bug where the variadic argument wouldn't match against the variadic parameter in certain scenarios. This was happening because I didn't realize that the `all_elements` iterator wouldn't keep on returning the variable element (which is correct, I just didn't realize it back then). I don't think we can use the `resize` method here because we don't know how many parameters this variadic argument is matching against as this is where the actual parameter matching occurs. ## Test Plan Expand test cases to consider a few more combinations of arguments and parameters which are variadic.
This commit is contained in:
parent
edeb45804e
commit
e1bb74b25a
6 changed files with 150 additions and 67 deletions
|
@ -642,6 +642,96 @@ def f(*args: int) -> int:
|
|||
reveal_type(f("foo")) # revealed: int
|
||||
```
|
||||
|
||||
### Variadic argument, variadic parameter
|
||||
|
||||
```toml
|
||||
[environment]
|
||||
python-version = "3.11"
|
||||
```
|
||||
|
||||
```py
|
||||
def f(*args: int) -> int:
|
||||
return 1
|
||||
|
||||
def _(args: list[str]) -> None:
|
||||
# error: [invalid-argument-type] "Argument to function `f` is incorrect: Expected `int`, found `str`"
|
||||
reveal_type(f(*args)) # revealed: int
|
||||
```
|
||||
|
||||
Considering a few different shapes of tuple for the splatted argument:
|
||||
|
||||
```py
|
||||
def f1(*args: str): ...
|
||||
def _(
|
||||
args1: tuple[str, ...],
|
||||
args2: tuple[str, *tuple[str, ...]],
|
||||
args3: tuple[str, *tuple[str, ...], str],
|
||||
args4: tuple[int, *tuple[str, ...]],
|
||||
args5: tuple[int, *tuple[str, ...], str],
|
||||
args6: tuple[*tuple[str, ...], str],
|
||||
args7: tuple[*tuple[str, ...], int],
|
||||
args8: tuple[int, *tuple[str, ...], int],
|
||||
args9: tuple[str, *tuple[str, ...], int],
|
||||
args10: tuple[str, *tuple[int, ...], str],
|
||||
):
|
||||
f1(*args1)
|
||||
f1(*args2)
|
||||
f1(*args3)
|
||||
f1(*args4) # error: [invalid-argument-type]
|
||||
f1(*args5) # error: [invalid-argument-type]
|
||||
f1(*args6)
|
||||
f1(*args7) # error: [invalid-argument-type]
|
||||
|
||||
# The reason for two errors here is because of the two fixed elements in the tuple of `args8`
|
||||
# which are both `int`
|
||||
# error: [invalid-argument-type]
|
||||
# error: [invalid-argument-type]
|
||||
f1(*args8)
|
||||
|
||||
f1(*args9) # error: [invalid-argument-type]
|
||||
f1(*args10) # error: [invalid-argument-type]
|
||||
```
|
||||
|
||||
### Mixed argument and parameter containing variadic
|
||||
|
||||
```toml
|
||||
[environment]
|
||||
python-version = "3.11"
|
||||
```
|
||||
|
||||
```py
|
||||
def f(x: int, *args: str) -> int:
|
||||
return 1
|
||||
|
||||
def _(
|
||||
args1: list[int],
|
||||
args2: tuple[int],
|
||||
args3: tuple[int, int],
|
||||
args4: tuple[int, ...],
|
||||
args5: tuple[int, *tuple[str, ...]],
|
||||
args6: tuple[int, int, *tuple[str, ...]],
|
||||
) -> None:
|
||||
# error: [invalid-argument-type] "Argument to function `f` is incorrect: Expected `str`, found `int`"
|
||||
reveal_type(f(*args1)) # revealed: int
|
||||
|
||||
# This shouldn't raise an error because the unpacking doesn't match the variadic parameter.
|
||||
reveal_type(f(*args2)) # revealed: int
|
||||
|
||||
# But, this should because the second tuple element is not assignable.
|
||||
# error: [invalid-argument-type] "Argument to function `f` is incorrect: Expected `str`, found `int`"
|
||||
reveal_type(f(*args3)) # revealed: int
|
||||
|
||||
# error: [invalid-argument-type] "Argument to function `f` is incorrect: Expected `str`, found `int`"
|
||||
reveal_type(f(*args4)) # revealed: int
|
||||
|
||||
# The first element of the tuple matches the required argument;
|
||||
# all subsequent elements match the variadic argument
|
||||
reveal_type(f(*args5)) # revealed: int
|
||||
|
||||
# error: [invalid-argument-type] "Argument to function `f` is incorrect: Expected `str`, found `int`"
|
||||
reveal_type(f(*args6)) # revealed: int
|
||||
```
|
||||
|
||||
### Keyword argument, positional-or-keyword parameter
|
||||
|
||||
```py
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue