|
38 | 38 | Instance, |
39 | 39 | LiteralType, |
40 | 40 | NoneType, |
| 41 | + NormalizedCallableType, |
41 | 42 | Overloaded, |
42 | 43 | Parameters, |
43 | 44 | ParamSpecType, |
@@ -626,8 +627,10 @@ def visit_unpack_type(self, left: UnpackType) -> bool: |
626 | 627 | return False |
627 | 628 |
|
628 | 629 | def visit_parameters(self, left: Parameters) -> bool: |
629 | | - right = self.right |
630 | | - if isinstance(right, Parameters) or isinstance(right, CallableType): |
| 630 | + if isinstance(self.right, Parameters) or isinstance(self.right, CallableType): |
| 631 | + right = self.right |
| 632 | + if isinstance(right, CallableType): |
| 633 | + right = right.with_unpacked_kwargs() |
631 | 634 | return are_parameters_compatible( |
632 | 635 | left, |
633 | 636 | right, |
@@ -671,7 +674,7 @@ def visit_callable_type(self, left: CallableType) -> bool: |
671 | 674 | elif isinstance(right, Parameters): |
672 | 675 | # this doesn't check return types.... but is needed for is_equivalent |
673 | 676 | return are_parameters_compatible( |
674 | | - left, |
| 677 | + left.with_unpacked_kwargs(), |
675 | 678 | right, |
676 | 679 | is_compat=self._is_subtype, |
677 | 680 | ignore_pos_arg_names=self.subtype_context.ignore_pos_arg_names, |
@@ -1249,6 +1252,10 @@ def g(x: int) -> int: ... |
1249 | 1252 | If the 'some_check' function is also symmetric, the two calls would be equivalent |
1250 | 1253 | whether or not we check the args covariantly. |
1251 | 1254 | """ |
| 1255 | + # Normalize both types before comparing them. |
| 1256 | + left = left.with_unpacked_kwargs() |
| 1257 | + right = right.with_unpacked_kwargs() |
| 1258 | + |
1252 | 1259 | if is_compat_return is None: |
1253 | 1260 | is_compat_return = is_compat |
1254 | 1261 |
|
@@ -1313,8 +1320,8 @@ def g(x: int) -> int: ... |
1313 | 1320 |
|
1314 | 1321 |
|
1315 | 1322 | def are_parameters_compatible( |
1316 | | - left: Parameters | CallableType, |
1317 | | - right: Parameters | CallableType, |
| 1323 | + left: Parameters | NormalizedCallableType, |
| 1324 | + right: Parameters | NormalizedCallableType, |
1318 | 1325 | *, |
1319 | 1326 | is_compat: Callable[[Type, Type], bool], |
1320 | 1327 | ignore_pos_arg_names: bool = False, |
@@ -1535,11 +1542,11 @@ def new_is_compat(left: Type, right: Type) -> bool: |
1535 | 1542 |
|
1536 | 1543 |
|
1537 | 1544 | def unify_generic_callable( |
1538 | | - type: CallableType, |
1539 | | - target: CallableType, |
| 1545 | + type: NormalizedCallableType, |
| 1546 | + target: NormalizedCallableType, |
1540 | 1547 | ignore_return: bool, |
1541 | 1548 | return_constraint_direction: int | None = None, |
1542 | | -) -> CallableType | None: |
| 1549 | +) -> NormalizedCallableType | None: |
1543 | 1550 | """Try to unify a generic callable type with another callable type. |
1544 | 1551 |
|
1545 | 1552 | Return unified CallableType if successful; otherwise, return None. |
@@ -1576,7 +1583,7 @@ def report(*args: Any) -> None: |
1576 | 1583 | ) |
1577 | 1584 | if had_errors: |
1578 | 1585 | return None |
1579 | | - return applied |
| 1586 | + return cast(NormalizedCallableType, applied) |
1580 | 1587 |
|
1581 | 1588 |
|
1582 | 1589 | def try_restrict_literal_union(t: UnionType, s: Type) -> list[Type] | None: |
|
0 commit comments