Skip to content

Commit 6a1f150

Browse files
committed
Consider name only for standard and keyword-only parameters
1 parent 9839893 commit 6a1f150

File tree

2 files changed

+60
-28
lines changed

2 files changed

+60
-28
lines changed

crates/red_knot_python_semantic/resources/mdtest/type_properties/is_equivalent_to.md

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,29 @@ other callable should also have a default value.
130130
from knot_extensions import CallableTypeFromFunction, is_equivalent_to, static_assert
131131
from typing import Callable
132132

133-
def c1(a: int, /, b: float, c: bool = False, *args: int, d: int = 1, e: str, **kwargs: float) -> None: ...
134-
def c2(a: int, /, b: float, c: bool = True, *args: int, d: int = 2, e: str, **kwargs: float) -> None: ...
133+
def f1(a: int = 1) -> None: ...
134+
def f2(a: int = 2) -> None: ...
135135

136-
static_assert(is_equivalent_to(CallableTypeFromFunction[c1], CallableTypeFromFunction[c2]))
136+
static_assert(is_equivalent_to(CallableTypeFromFunction[f1], CallableTypeFromFunction[f2]))
137+
```
138+
139+
The names of the positional-only, variadic and keyword-variadic parameters does not need to be the
140+
same.
141+
142+
```py
143+
def f3(a1: int, /, *args1: int, **kwargs2: int) -> None: ...
144+
def f4(a2: int, /, *args2: int, **kwargs1: int) -> None: ...
145+
146+
static_assert(is_equivalent_to(CallableTypeFromFunction[f3], CallableTypeFromFunction[f4]))
147+
```
148+
149+
Putting it all together, the following two callables are equivalent:
150+
151+
```py
152+
def f5(a1: int, /, b: float, c: bool = False, *args1: int, d: int = 1, e: str, **kwargs1: float) -> None: ...
153+
def f6(a2: int, /, b: float, c: bool = True, *args2: int, d: int = 2, e: str, **kwargs2: float) -> None: ...
154+
155+
static_assert(is_equivalent_to(CallableTypeFromFunction[f5], CallableTypeFromFunction[f6]))
137156
```
138157

139158
### Not equivalent

crates/red_knot_python_semantic/src/types.rs

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4576,34 +4576,47 @@ impl<'db> GeneralCallableType<'db> {
45764576
}
45774577

45784578
for (self_parameter, other_parameter) in self_parameters.iter().zip(other_parameters) {
4579-
if self_parameter.name() != other_parameter.name() {
4580-
return false;
4581-
}
4579+
match (self_parameter.kind(), other_parameter.kind()) {
4580+
(
4581+
ParameterKind::PositionalOnly {
4582+
default_ty: self_default,
4583+
..
4584+
},
4585+
ParameterKind::PositionalOnly {
4586+
default_ty: other_default,
4587+
..
4588+
},
4589+
) if self_default.is_some() == other_default.is_some() => {}
45824590

4583-
if self_parameter.default_type().is_some() != other_parameter.default_type().is_some() {
4584-
return false;
4585-
}
4591+
(
4592+
ParameterKind::PositionalOrKeyword {
4593+
name: self_name,
4594+
default_ty: self_default,
4595+
},
4596+
ParameterKind::PositionalOrKeyword {
4597+
name: other_name,
4598+
default_ty: other_default,
4599+
},
4600+
) if self_default.is_some() == other_default.is_some()
4601+
&& self_name == other_name => {}
4602+
4603+
(ParameterKind::Variadic { .. }, ParameterKind::Variadic { .. }) => {}
45864604

4587-
if !matches!(
4588-
(self_parameter.kind(), other_parameter.kind()),
45894605
(
4590-
ParameterKind::PositionalOnly { .. },
4591-
ParameterKind::PositionalOnly { .. }
4592-
) | (
4593-
ParameterKind::PositionalOrKeyword { .. },
4594-
ParameterKind::PositionalOrKeyword { .. }
4595-
) | (
4596-
ParameterKind::Variadic { .. },
4597-
ParameterKind::Variadic { .. }
4598-
) | (
4599-
ParameterKind::KeywordOnly { .. },
4600-
ParameterKind::KeywordOnly { .. }
4601-
) | (
4602-
ParameterKind::KeywordVariadic { .. },
4603-
ParameterKind::KeywordVariadic { .. }
4604-
)
4605-
) {
4606-
return false;
4606+
ParameterKind::KeywordOnly {
4607+
name: self_name,
4608+
default_ty: self_default,
4609+
},
4610+
ParameterKind::KeywordOnly {
4611+
name: other_name,
4612+
default_ty: other_default,
4613+
},
4614+
) if self_default.is_some() == other_default.is_some()
4615+
&& self_name == other_name => {}
4616+
4617+
(ParameterKind::KeywordVariadic { .. }, ParameterKind::KeywordVariadic { .. }) => {}
4618+
4619+
_ => return false,
46074620
}
46084621

46094622
if !is_equivalent(

0 commit comments

Comments
 (0)