|
38 | 38 | Instance, |
39 | 39 | LiteralType, |
40 | 40 | NoneType, |
| 41 | + NormalizedCallableType, |
41 | 42 | Overloaded, |
42 | 43 | Parameters, |
43 | 44 | ParamSpecType, |
@@ -591,8 +592,10 @@ def visit_unpack_type(self, left: UnpackType) -> bool: |
591 | 592 | return False |
592 | 593 |
|
593 | 594 | def visit_parameters(self, left: Parameters) -> bool: |
594 | | - right = self.right |
595 | | - if isinstance(right, Parameters) or isinstance(right, CallableType): |
| 595 | + if isinstance(self.right, Parameters) or isinstance(self.right, CallableType): |
| 596 | + right = self.right |
| 597 | + if isinstance(right, CallableType): |
| 598 | + right = right.with_unpacked_kwargs() |
596 | 599 | return are_parameters_compatible( |
597 | 600 | left, |
598 | 601 | right, |
@@ -636,7 +639,7 @@ def visit_callable_type(self, left: CallableType) -> bool: |
636 | 639 | elif isinstance(right, Parameters): |
637 | 640 | # this doesn't check return types.... but is needed for is_equivalent |
638 | 641 | return are_parameters_compatible( |
639 | | - left, |
| 642 | + left.with_unpacked_kwargs(), |
640 | 643 | right, |
641 | 644 | is_compat=self._is_subtype, |
642 | 645 | ignore_pos_arg_names=self.subtype_context.ignore_pos_arg_names, |
@@ -1213,6 +1216,10 @@ def g(x: int) -> int: ... |
1213 | 1216 | If the 'some_check' function is also symmetric, the two calls would be equivalent |
1214 | 1217 | whether or not we check the args covariantly. |
1215 | 1218 | """ |
| 1219 | + # Normalize both types before comparing them. |
| 1220 | + left = left.with_unpacked_kwargs() |
| 1221 | + right = right.with_unpacked_kwargs() |
| 1222 | + |
1216 | 1223 | if is_compat_return is None: |
1217 | 1224 | is_compat_return = is_compat |
1218 | 1225 |
|
@@ -1277,8 +1284,8 @@ def g(x: int) -> int: ... |
1277 | 1284 |
|
1278 | 1285 |
|
1279 | 1286 | def are_parameters_compatible( |
1280 | | - left: Parameters | CallableType, |
1281 | | - right: Parameters | CallableType, |
| 1287 | + left: Parameters | NormalizedCallableType, |
| 1288 | + right: Parameters | NormalizedCallableType, |
1282 | 1289 | *, |
1283 | 1290 | is_compat: Callable[[Type, Type], bool], |
1284 | 1291 | ignore_pos_arg_names: bool = False, |
@@ -1499,11 +1506,11 @@ def new_is_compat(left: Type, right: Type) -> bool: |
1499 | 1506 |
|
1500 | 1507 |
|
1501 | 1508 | def unify_generic_callable( |
1502 | | - type: CallableType, |
1503 | | - target: CallableType, |
| 1509 | + type: NormalizedCallableType, |
| 1510 | + target: NormalizedCallableType, |
1504 | 1511 | ignore_return: bool, |
1505 | 1512 | return_constraint_direction: int | None = None, |
1506 | | -) -> CallableType | None: |
| 1513 | +) -> NormalizedCallableType | None: |
1507 | 1514 | """Try to unify a generic callable type with another callable type. |
1508 | 1515 |
|
1509 | 1516 | Return unified CallableType if successful; otherwise, return None. |
@@ -1540,7 +1547,7 @@ def report(*args: Any) -> None: |
1540 | 1547 | ) |
1541 | 1548 | if had_errors: |
1542 | 1549 | return None |
1543 | | - return applied |
| 1550 | + return cast(NormalizedCallableType, applied) |
1544 | 1551 |
|
1545 | 1552 |
|
1546 | 1553 | def try_restrict_literal_union(t: UnionType, s: Type) -> list[Type] | None: |
|
0 commit comments