From 90f420f9c047b6a1e0f03e3b459b8060fe6be1da Mon Sep 17 00:00:00 2001 From: A5rocks Date: Fri, 26 Nov 2021 01:46:38 +0900 Subject: [PATCH 1/4] Switch target around Time for a quick run of mypy-primer! --- mypy/checker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/checker.py b/mypy/checker.py index 109a3b1f15d2..a31dedd541f3 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -585,7 +585,7 @@ def check_overlapping_overloads(self, defn: OverloadedFuncDef) -> None: # This is to match the direction the implementation's return # needs to be compatible in. if impl_type.variables: - impl = unify_generic_callable(impl_type, sig1, + impl = unify_generic_callable(sig1, impl_type, ignore_return=False, return_constraint_direction=SUPERTYPE_OF) if impl is None: From d77d4bded55f24cdaa30a0445491be1bb5398000 Mon Sep 17 00:00:00 2001 From: A5rocks Date: Fri, 26 Nov 2021 04:19:56 +0900 Subject: [PATCH 2/4] Attempt 2 --- mypy/checker.py | 2 +- mypy/subtypes.py | 27 +++++++++++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/mypy/checker.py b/mypy/checker.py index a31dedd541f3..109a3b1f15d2 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -585,7 +585,7 @@ def check_overlapping_overloads(self, defn: OverloadedFuncDef) -> None: # This is to match the direction the implementation's return # needs to be compatible in. if impl_type.variables: - impl = unify_generic_callable(sig1, impl_type, + impl = unify_generic_callable(impl_type, sig1, ignore_return=False, return_constraint_direction=SUPERTYPE_OF) if impl is None: diff --git a/mypy/subtypes.py b/mypy/subtypes.py index bbde38c5f92f..8f2ced48197d 100644 --- a/mypy/subtypes.py +++ b/mypy/subtypes.py @@ -1198,10 +1198,29 @@ def unify_generic_callable(type: CallableType, target: CallableType, return_constraint_direction = mypy.constraints.SUBTYPE_OF constraints: List[mypy.constraints.Constraint] = [] - for arg_type, target_arg_type in zip(type.arg_types, target.arg_types): - c = mypy.constraints.infer_constraints( - arg_type, target_arg_type, mypy.constraints.SUPERTYPE_OF) - constraints.extend(c) + # check by names + argument_names_map = {} + # `is_unsafe_overlapping_overload_signatures` calls this both ways + for i in range(len(target.arg_types)): + if target.arg_names[i]: + argument_names_map[target.arg_names[i]] = target.arg_types[i] + for i in range(len(type.arg_types)): + if type.arg_names[i]: + argument_names_map[type.arg_names[i]] = type.arg_types[i] + for i in range(len(target.arg_types)): + if target.arg_names[i]: + c = mypy.constraints.infer_constraints( + argument_names_map[target.arg_names[i]], target.arg_types[i], mypy.constraints.SUPERTYPE_OF) + constraints.extend(c) + # check pos-only arguments + for arg, target_arg in zip(type.formal_arguments(), target.formal_arguments()): + if arg.pos and target_arg.pos: + c = mypy.constraints.infer_constraints( + arg.type, target_arg.type, mypy.constraints.SUPERTYPE_OF) + constraints.extend(c) + else: + # optimization, no more positional arguments + break if not ignore_return: c = mypy.constraints.infer_constraints( type.ret_type, target.ret_type, return_constraint_direction) From a4554282afe873a30398099111a290e40124e79b Mon Sep 17 00:00:00 2001 From: A5rocks Date: Fri, 26 Nov 2021 04:54:02 +0900 Subject: [PATCH 3/4] Somehow missed this change... --- mypy/subtypes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/subtypes.py b/mypy/subtypes.py index 8f2ced48197d..e7257a9c41dd 100644 --- a/mypy/subtypes.py +++ b/mypy/subtypes.py @@ -1216,7 +1216,7 @@ def unify_generic_callable(type: CallableType, target: CallableType, for arg, target_arg in zip(type.formal_arguments(), target.formal_arguments()): if arg.pos and target_arg.pos: c = mypy.constraints.infer_constraints( - arg.type, target_arg.type, mypy.constraints.SUPERTYPE_OF) + arg.typ, target_arg.typ, mypy.constraints.SUPERTYPE_OF) constraints.extend(c) else: # optimization, no more positional arguments From 94f4ce12f55b9a7b5a43a9f9e868584a6bf60bb0 Mon Sep 17 00:00:00 2001 From: A5rocks Date: Fri, 26 Nov 2021 07:49:54 +0900 Subject: [PATCH 4/4] FormalArgument#pos can be 0... --- mypy/subtypes.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mypy/subtypes.py b/mypy/subtypes.py index e7257a9c41dd..936c16a070ca 100644 --- a/mypy/subtypes.py +++ b/mypy/subtypes.py @@ -1210,11 +1210,13 @@ def unify_generic_callable(type: CallableType, target: CallableType, for i in range(len(target.arg_types)): if target.arg_names[i]: c = mypy.constraints.infer_constraints( - argument_names_map[target.arg_names[i]], target.arg_types[i], mypy.constraints.SUPERTYPE_OF) + argument_names_map[target.arg_names[i]], + target.arg_types[i], + mypy.constraints.SUPERTYPE_OF) constraints.extend(c) # check pos-only arguments for arg, target_arg in zip(type.formal_arguments(), target.formal_arguments()): - if arg.pos and target_arg.pos: + if arg.pos is not None and target_arg.pos is not None: c = mypy.constraints.infer_constraints( arg.typ, target_arg.typ, mypy.constraints.SUPERTYPE_OF) constraints.extend(c)