@@ -1199,13 +1199,14 @@ def check_func_def(
11991199 # Push return type.
12001200 self .return_types .append (typ .ret_type )
12011201
1202+ with self .scope .push_function (defn ):
1203+ # We temporary push the definition to get the self type as
1204+ # visible from *inside* of this function/method.
1205+ ref_type : Type | None = self .scope .active_self_type ()
1206+
12021207 # Store argument types.
12031208 for i in range (len (typ .arg_types )):
12041209 arg_type = typ .arg_types [i ]
1205- with self .scope .push_function (defn ):
1206- # We temporary push the definition to get the self type as
1207- # visible from *inside* of this function/method.
1208- ref_type : Type | None = self .scope .active_self_type ()
12091210 if (
12101211 isinstance (defn , FuncDef )
12111212 and ref_type is not None
@@ -1215,30 +1216,31 @@ def check_func_def(
12151216 ):
12161217 if defn .is_class or defn .name == "__new__" :
12171218 ref_type = mypy .types .TypeType .make_normalized (ref_type )
1218- # This level of erasure matches the one in checkmember.check_self_arg(),
1219- # better keep these two checks consistent.
1220- erased = get_proper_type (erase_typevars (erase_to_bound (arg_type )))
1221- if not is_subtype (ref_type , erased , ignore_type_params = True ):
1222- if (
1223- isinstance (erased , Instance )
1224- and erased .type .is_protocol
1225- or isinstance (erased , TypeType )
1226- and isinstance (erased .item , Instance )
1227- and erased .item .type .is_protocol
1228- ):
1229- # We allow the explicit self-type to be not a supertype of
1230- # the current class if it is a protocol. For such cases
1231- # the consistency check will be performed at call sites.
1232- msg = None
1233- elif typ .arg_names [i ] in {"self" , "cls" }:
1234- msg = message_registry .ERASED_SELF_TYPE_NOT_SUPERTYPE .format (
1235- erased .str_with_options (self .options ),
1236- ref_type .str_with_options (self .options ),
1237- )
1238- else :
1239- msg = message_registry .MISSING_OR_INVALID_SELF_TYPE
1240- if msg :
1241- self .fail (msg , defn )
1219+ if not is_same_type (arg_type , ref_type ):
1220+ # This level of erasure matches the one in checkmember.check_self_arg(),
1221+ # better keep these two checks consistent.
1222+ erased = get_proper_type (erase_typevars (erase_to_bound (arg_type )))
1223+ if not is_subtype (ref_type , erased , ignore_type_params = True ):
1224+ if (
1225+ isinstance (erased , Instance )
1226+ and erased .type .is_protocol
1227+ or isinstance (erased , TypeType )
1228+ and isinstance (erased .item , Instance )
1229+ and erased .item .type .is_protocol
1230+ ):
1231+ # We allow the explicit self-type to be not a supertype of
1232+ # the current class if it is a protocol. For such cases
1233+ # the consistency check will be performed at call sites.
1234+ msg = None
1235+ elif typ .arg_names [i ] in {"self" , "cls" }:
1236+ msg = message_registry .ERASED_SELF_TYPE_NOT_SUPERTYPE .format (
1237+ erased .str_with_options (self .options ),
1238+ ref_type .str_with_options (self .options ),
1239+ )
1240+ else :
1241+ msg = message_registry .MISSING_OR_INVALID_SELF_TYPE
1242+ if msg :
1243+ self .fail (msg , defn )
12421244 elif isinstance (arg_type , TypeVarType ):
12431245 # Refuse covariant parameter type variables
12441246 # TODO: check recursively for inner type variables
0 commit comments