|
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