@@ -1015,13 +1015,13 @@ def expand_typevars(self, defn: FuncItem,
1015
1015
else :
1016
1016
return [(defn , typ )]
1017
1017
1018
- def check_method_override (self , defn : FuncBase ) -> None :
1018
+ def check_method_override (self , defn : Union [ FuncBase , Decorator ] ) -> None :
1019
1019
"""Check if function definition is compatible with base classes."""
1020
1020
# Check against definitions in base classes.
1021
1021
for base in defn .info .mro [1 :]:
1022
1022
self .check_method_or_accessor_override_for_base (defn , base )
1023
1023
1024
- def check_method_or_accessor_override_for_base (self , defn : FuncBase ,
1024
+ def check_method_or_accessor_override_for_base (self , defn : Union [ FuncBase , Decorator ] ,
1025
1025
base : TypeInfo ) -> None :
1026
1026
"""Check if method definition is compatible with a base class."""
1027
1027
if base :
@@ -1041,13 +1041,26 @@ def check_method_or_accessor_override_for_base(self, defn: FuncBase,
1041
1041
base )
1042
1042
1043
1043
def check_method_override_for_base_with_name (
1044
- self , defn : FuncBase , name : str , base : TypeInfo ) -> None :
1044
+ self , defn : Union [ FuncBase , Decorator ] , name : str , base : TypeInfo ) -> None :
1045
1045
base_attr = base .names .get (name )
1046
1046
if base_attr :
1047
1047
# The name of the method is defined in the base class.
1048
1048
1049
+ # Point errors at the 'def' line (important for backward compatibility
1050
+ # of type ignores).
1051
+ if not isinstance (defn , Decorator ):
1052
+ context = defn
1053
+ else :
1054
+ context = defn .func
1049
1055
# Construct the type of the overriding method.
1050
- typ = bind_self (self .function_type (defn ), self .scope .active_self_type ())
1056
+ if isinstance (defn , FuncBase ):
1057
+ typ = self .function_type (defn ) # type: Type
1058
+ else :
1059
+ assert defn .var .is_ready
1060
+ assert defn .var .type is not None
1061
+ typ = defn .var .type
1062
+ if isinstance (typ , FunctionLike ) and not is_static (context ):
1063
+ typ = bind_self (typ , self .scope .active_self_type ())
1051
1064
# Map the overridden method type to subtype context so that
1052
1065
# it can be checked for compatibility.
1053
1066
original_type = base_attr .type
@@ -1058,23 +1071,33 @@ def check_method_override_for_base_with_name(
1058
1071
original_type = self .function_type (base_attr .node .func )
1059
1072
else :
1060
1073
assert False , str (base_attr .node )
1061
- if isinstance (original_type , FunctionLike ):
1062
- original = map_type_from_supertype (
1063
- bind_self (original_type , self .scope .active_self_type ()),
1064
- defn .info , base )
1074
+ if isinstance (original_type , AnyType ) or isinstance (typ , AnyType ):
1075
+ pass
1076
+ elif isinstance (original_type , FunctionLike ) and isinstance (typ , FunctionLike ):
1077
+ if (isinstance (base_attr .node , (FuncBase , Decorator ))
1078
+ and not is_static (base_attr .node )):
1079
+ bound = bind_self (original_type , self .scope .active_self_type ())
1080
+ else :
1081
+ bound = original_type
1082
+ original = map_type_from_supertype (bound , defn .info , base )
1065
1083
# Check that the types are compatible.
1066
1084
# TODO overloaded signatures
1067
1085
self .check_override (typ ,
1068
1086
cast (FunctionLike , original ),
1069
1087
defn .name (),
1070
1088
name ,
1071
1089
base .name (),
1072
- defn )
1073
- elif isinstance (original_type , AnyType ):
1090
+ context )
1091
+ elif is_equivalent (original_type , typ ):
1092
+ # Assume invariance for a non-callable attribute here. Note
1093
+ # that this doesn't affect read-only properties which can have
1094
+ # covariant overrides.
1095
+ #
1096
+ # TODO: Allow covariance for read-only attributes?
1074
1097
pass
1075
1098
else :
1076
1099
self .msg .signature_incompatible_with_supertype (
1077
- defn .name (), name , base .name (), defn )
1100
+ defn .name (), name , base .name (), context )
1078
1101
1079
1102
def check_override (self , override : FunctionLike , original : FunctionLike ,
1080
1103
name : str , name_in_super : str , supertype : str ,
@@ -1966,7 +1989,7 @@ def try_infer_partial_type_from_indexed_assignment(
1966
1989
if not self .current_node_deferred :
1967
1990
var .type = self .named_generic_type ('builtins.dict' ,
1968
1991
[full_key_type , full_value_type ])
1969
- del partial_types [var ]
1992
+ del partial_types [var ]
1970
1993
1971
1994
def visit_expression_stmt (self , s : ExpressionStmt ) -> None :
1972
1995
self .expr_checker .accept (s .expr , allow_none_return = True , always_allow_any = True )
@@ -2015,7 +2038,7 @@ def check_return_stmt(self, s: ReturnStmt) -> None:
2015
2038
# function is not declared to return Any)
2016
2039
if (self .options .warn_return_any and
2017
2040
not is_proper_subtype (AnyType (TypeOfAny .special_form ), return_type )):
2018
- self .warn ( messages . RETURN_ANY . format (return_type ) , s )
2041
+ self .msg . incorrectly_returning_any (return_type , s )
2019
2042
return
2020
2043
2021
2044
# Disallow return expressions in functions declared to return
@@ -2364,9 +2387,11 @@ def visit_decorator(self, e: Decorator) -> None:
2364
2387
e .var .is_ready = True
2365
2388
return
2366
2389
2367
- e .func .accept (self )
2390
+ self .check_func_item (e .func , name = e .func .name ())
2391
+
2392
+ # Process decorators from the inside out to determine decorated signature, which
2393
+ # may be different from the declared signature.
2368
2394
sig = self .function_type (e .func ) # type: Type
2369
- # Process decorators from the inside out.
2370
2395
for d in reversed (e .decorators ):
2371
2396
if refers_to_fullname (d , 'typing.overload' ):
2372
2397
self .fail ('Single overload definition, multiple required' , e )
@@ -2387,6 +2412,8 @@ def visit_decorator(self, e: Decorator) -> None:
2387
2412
e .var .is_ready = True
2388
2413
if e .func .is_property :
2389
2414
self .check_incompatible_property_override (e )
2415
+ if e .func .info and not e .func .is_dynamic ():
2416
+ self .check_method_override (e )
2390
2417
2391
2418
def check_for_untyped_decorator (self ,
2392
2419
func : FuncDef ,
@@ -3316,3 +3343,13 @@ def is_untyped_decorator(typ: Optional[Type]) -> bool:
3316
3343
if not typ or not isinstance (typ , CallableType ):
3317
3344
return True
3318
3345
return typ .implicit
3346
+
3347
+
3348
+ def is_static (func : Union [FuncBase , Decorator ]) -> bool :
3349
+ if isinstance (func , Decorator ):
3350
+ return is_static (func .func )
3351
+ elif isinstance (func , OverloadedFuncDef ):
3352
+ return any (is_static (item ) for item in func .items )
3353
+ elif isinstance (func , FuncItem ):
3354
+ return func .is_static
3355
+ return False
0 commit comments