Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1313,7 +1313,7 @@ Variadic parameter in a subtype can only be used to match against an unmatched p
parameters from the supertype, not any other parameter kind.

```py
from ty_extensions import CallableTypeOf, is_subtype_of, static_assert
from ty_extensions import CallableTypeOf, is_subtype_of, is_assignable_to, static_assert

def variadic(*args: int) -> None: ...

Expand Down Expand Up @@ -1376,6 +1376,16 @@ static_assert(is_subtype_of(CallableTypeOf[variadic_a], CallableTypeOf[standard_
static_assert(not is_subtype_of(CallableTypeOf[variadic_b], CallableTypeOf[standard_int]))
```

A variadic positional parameter alone cannot match a positional-or-keyword parameter because
variadic positional parameters can only be called positionally.

```py
def only_variadic(*args: int) -> None: ...

static_assert(not is_subtype_of(CallableTypeOf[only_variadic], CallableTypeOf[standard_int]))
static_assert(not is_assignable_to(CallableTypeOf[only_variadic], CallableTypeOf[standard_int]))
```

#### Keyword-only

For keyword-only parameters, the name should be the same:
Expand Down
12 changes: 9 additions & 3 deletions crates/ty_python_semantic/src/types/signatures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1404,9 +1404,15 @@ impl<'db> Signature<'db> {

loop {
let Some(next_parameter) = parameters.next() else {
// All parameters have been checked or both the parameter lists were empty. In
// either case, `self` is a subtype of `other`.
return result;
if other_keywords.is_empty() {
// All parameters have been checked or both the parameter lists were empty.
// In either case, `self` is a subtype of `other`.
return result;
}
// There are keyword parameters in `other` that were only matched positionally
// against a variadic parameter in `self`. We need to verify that they can also
// be matched as keyword arguments, which is done after this loop.
break;
};

match next_parameter {
Expand Down
Loading