[ty] Consider keyword arguments when unpacking a variadic argument#22796
[ty] Consider keyword arguments when unpacking a variadic argument#22796dhruvmanila merged 1 commit intomainfrom
Conversation
Typing conformance resultsNo changes detected ✅ |
|
992fc8a to
b175d81
Compare
b175d81 to
802bb74
Compare
|
| Lint rule | Added | Removed | Changed |
|---|---|---|---|
parameter-already-assigned |
0 | 120 | 0 |
unused-ignore-comment |
21 | 0 | 0 |
no-matching-overload |
0 | 13 | 0 |
invalid-argument-type |
0 | 7 | 3 |
invalid-await |
0 | 2 | 6 |
invalid-return-type |
4 | 0 | 4 |
invalid-assignment |
0 | 0 | 5 |
possibly-missing-attribute |
0 | 3 | 1 |
unresolved-attribute |
0 | 0 | 2 |
| Total | 25 | 145 | 21 |
| # Explicit keyword argument takes precedence over variable-length variadic expansion. | ||
| # The list unpacking should only fill `a` and `b`, leaving `c` for the keyword argument. | ||
| def _(args: list[str]) -> None: | ||
| f(*args, c=1.0) |
There was a problem hiding this comment.
I guess we could consider still flagging this as a separate error code? Since the length of the args iterable is unknown, we cannot verify that the call will definitely succeed; some users who want very strict typing might still want to know about that.
I agree that we should err on the side of leniency here, though -- if we did have a separate error code for that, it should definitely be disabled by default. It's too strict for most users.
There was a problem hiding this comment.
I think if we were being consistent about the strict version, it would go beyond what main currently does -- really any * unpacking of anything other than a fixed-length tuple, to any function which doesn't take *args, is a call we can't verify is correct, which the strict diagnostic should be emitted on. I definitely think this is a separate (and low priority) feature, not something we should do in this PR.
There was a problem hiding this comment.
Yeah, that makes sense. I'll open a separate tracking issue for this.
Summary
fixes: astral-sh/ty#1584
This PR fixes a bug where ty would unpack a variadic argument consuming all the remaining unmatched parameters. The way this fix is implemented is by collecting the parameters for which an argument is provided via keyword e.g.,
func(foo=1). For example,In the above example,
mainwould currently raiseparameter-already-assignedbecause we don't know how many elements wouldargsunpack into so we consider assigning the type to all the remaining parameters. But, in the above caseyhas been provided as keyword argument explicitly.Now, there are other cases like
foo(*args, 1)orfoo(*args, *(1,))which is not considered in this PR i.e., this PR only handles explicit keyword argument and we would still emit diagnostic for positional, variadic, and keyword-variadic. Pyright behaves in the same way i.e., it only handles keyword argument while other type checkers (mypy, pyrefly) does not handle any cases. Refer to the new mdtest cases for all the cases.Test Plan
Add new mdtests.