@@ -1050,6 +1050,7 @@ def f(self: S) -> T: ...
10501050 new_items = []
10511051 if is_classmethod :
10521052 dispatched_arg_type = TypeType .make_normalized (dispatched_arg_type )
1053+ p_dispatched_arg_type = get_proper_type (dispatched_arg_type )
10531054
10541055 for item in items :
10551056 if not item .arg_types or item .arg_kinds [0 ] not in (ARG_POS , ARG_STAR ):
@@ -1058,36 +1059,42 @@ def f(self: S) -> T: ...
10581059 # This is pretty bad, so just return the original signature if
10591060 # there is at least one such error.
10601061 return functype
1061- else :
1062- selfarg = get_proper_type (item .arg_types [0 ])
1063- p_dispatched_arg_type = get_proper_type (dispatched_arg_type )
1064- if isinstance (selfarg , Instance ) and isinstance (p_dispatched_arg_type , Instance ):
1065- if selfarg .type is p_dispatched_arg_type .type and selfarg .args :
1066- if not is_overlapping_types (p_dispatched_arg_type , selfarg ):
1067- # This special casing is needed since `actual <: erased(template)`
1068- # logic below doesn't always work, and a more correct approach may
1069- # be tricky.
1070- continue
1071- # This matches similar special-casing in bind_self(), see more details there.
1072- self_callable = name == "__call__" and isinstance (selfarg , CallableType )
1073- if self_callable or is_subtype (
1074- dispatched_arg_type ,
1075- # This level of erasure matches the one in checker.check_func_def(),
1076- # better keep these two checks consistent.
1077- erase_typevars (erase_to_bound (selfarg )),
1078- # This is to work around the fact that erased ParamSpec and TypeVarTuple
1079- # callables are not always compatible with non-erased ones both ways.
1080- always_covariant = any (
1081- not isinstance (tv , TypeVarType ) for tv in get_all_type_vars (selfarg )
1082- ),
1083- ignore_pos_arg_names = True ,
1084- ):
1085- new_items .append (item )
1086- elif isinstance (selfarg , ParamSpecType ):
1087- # TODO: This is not always right. What's the most reasonable thing to do here?
1088- new_items .append (item )
1089- elif isinstance (selfarg , TypeVarTupleType ):
1090- raise NotImplementedError
1062+ selfarg = get_proper_type (item .arg_types [0 ])
1063+ if isinstance (selfarg , Instance ) and isinstance (p_dispatched_arg_type , Instance ):
1064+ if selfarg .type is p_dispatched_arg_type .type and selfarg .args :
1065+ if not is_overlapping_types (p_dispatched_arg_type , selfarg ):
1066+ # This special casing is needed since `actual <: erased(template)`
1067+ # logic below doesn't always work, and a more correct approach may
1068+ # be tricky.
1069+ continue
1070+ new_items .append (item )
1071+
1072+ if new_items :
1073+ items = new_items
1074+ new_items = []
1075+
1076+ for item in items :
1077+ selfarg = get_proper_type (item .arg_types [0 ])
1078+ # This matches similar special-casing in bind_self(), see more details there.
1079+ self_callable = name == "__call__" and isinstance (selfarg , CallableType )
1080+ if self_callable or is_subtype (
1081+ dispatched_arg_type ,
1082+ # This level of erasure matches the one in checker.check_func_def(),
1083+ # better keep these two checks consistent.
1084+ erase_typevars (erase_to_bound (selfarg )),
1085+ # This is to work around the fact that erased ParamSpec and TypeVarTuple
1086+ # callables are not always compatible with non-erased ones both ways.
1087+ always_covariant = any (
1088+ not isinstance (tv , TypeVarType ) for tv in get_all_type_vars (selfarg )
1089+ ),
1090+ ignore_pos_arg_names = True ,
1091+ ):
1092+ new_items .append (item )
1093+ elif isinstance (selfarg , ParamSpecType ):
1094+ # TODO: This is not always right. What's the most reasonable thing to do here?
1095+ new_items .append (item )
1096+ elif isinstance (selfarg , TypeVarTupleType ):
1097+ raise NotImplementedError
10911098 if not new_items :
10921099 # Choose first item for the message (it may be not very helpful for overloads).
10931100 msg .incompatible_self_argument (
0 commit comments