@@ -2134,40 +2134,17 @@ def check_method_or_accessor_override_for_base(
21342134 return None
21352135 return found_base_method
21362136
2137- def check_setter_type_override (
2138- self , defn : OverloadedFuncDef , base_attr : SymbolTableNode , base : TypeInfo
2139- ) -> None :
2137+ def check_setter_type_override (self , defn : OverloadedFuncDef , base : TypeInfo ) -> None :
21402138 """Check override of a setter type of a mutable attribute.
21412139
21422140 Currently, this should be only called when either base node or the current node
21432141 is a custom settable property (i.e. where setter type is different from getter type).
21442142 Note that this check is contravariant.
21452143 """
2146- base_node = base_attr .node
2147- assert isinstance (base_node , (OverloadedFuncDef , Var ))
2148- original_type , is_original_setter = get_raw_setter_type (base_node )
2149- if isinstance (base_node , Var ):
2150- expanded_type = map_type_from_supertype (original_type , defn .info , base )
2151- original_type = get_proper_type (
2152- expand_self_type (base_node , expanded_type , fill_typevars (defn .info ))
2153- )
2154- else :
2155- assert isinstance (original_type , ProperType )
2156- assert isinstance (original_type , CallableType )
2157- original_type = self .bind_and_map_method (base_attr , original_type , defn .info , base )
2158- assert isinstance (original_type , CallableType )
2159- if is_original_setter :
2160- original_type = original_type .arg_types [0 ]
2161- else :
2162- original_type = original_type .ret_type
2163-
2164- typ , is_setter = get_raw_setter_type (defn )
2165- assert isinstance (typ , ProperType ) and isinstance (typ , CallableType )
2166- typ = bind_self (typ , self .scope .active_self_type ())
2167- if is_setter :
2168- typ = typ .arg_types [0 ]
2169- else :
2170- typ = typ .ret_type
2144+ typ , _ = self .node_type_from_base (defn , defn .info , setter_type = True )
2145+ original_type , _ = self .node_type_from_base (defn , base , setter_type = True )
2146+ # The caller should handle deferrals.
2147+ assert typ is not None and original_type is not None
21712148
21722149 if not is_subtype (original_type , typ ):
21732150 self .msg .incompatible_setter_override (defn .items [1 ], typ , original_type , base )
@@ -2192,28 +2169,19 @@ def check_method_override_for_base_with_name(
21922169 context = defn .func
21932170
21942171 # Construct the type of the overriding method.
2195- # TODO: this logic is much less complete than similar one in checkmember.py
21962172 if isinstance (defn , (FuncDef , OverloadedFuncDef )):
2197- typ : Type = self .function_type (defn )
21982173 override_class_or_static = defn .is_class or defn .is_static
2199- override_class = defn .is_class
22002174 else :
2201- assert defn .var .is_ready
2202- assert defn .var .type is not None
2203- typ = defn .var .type
22042175 override_class_or_static = defn .func .is_class or defn .func .is_static
2205- override_class = defn .func .is_class
2206- typ = get_proper_type (typ )
2207- if isinstance (typ , FunctionLike ) and not is_static (context ):
2208- typ = bind_self (typ , self .scope .active_self_type (), is_classmethod = override_class )
2209- # Map the overridden method type to subtype context so that
2210- # it can be checked for compatibility.
2211- original_type = get_proper_type (base_attr .type )
2176+ typ , _ = self .node_type_from_base (defn , defn .info )
2177+ assert typ is not None
2178+
22122179 original_node = base_attr .node
22132180 # `original_type` can be partial if (e.g.) it is originally an
22142181 # instance variable from an `__init__` block that becomes deferred.
22152182 supertype_ready = True
2216- if original_type is None or isinstance (original_type , PartialType ):
2183+ original_type , _ = self .node_type_from_base (defn , base , name_override = name )
2184+ if original_type is None :
22172185 supertype_ready = False
22182186 if self .pass_num < self .last_pass :
22192187 # If there are passes left, defer this node until next pass,
@@ -2255,7 +2223,7 @@ def check_method_override_for_base_with_name(
22552223 # supertype is not known precisely.
22562224 if supertype_ready :
22572225 always_allow_covariant = True
2258- self .check_setter_type_override (defn , base_attr , base )
2226+ self .check_setter_type_override (defn , base )
22592227
22602228 if isinstance (original_node , (FuncDef , OverloadedFuncDef )):
22612229 original_class_or_static = original_node .is_class or original_node .is_static
@@ -2265,41 +2233,24 @@ def check_method_override_for_base_with_name(
22652233 else :
22662234 original_class_or_static = False # a variable can't be class or static
22672235
2268- if isinstance (original_type , FunctionLike ):
2269- original_type = self .bind_and_map_method (base_attr , original_type , defn .info , base )
2270- if original_node and is_property (original_node ):
2271- original_type = get_property_type (original_type )
2272-
2273- if isinstance (original_node , Var ):
2274- expanded_type = map_type_from_supertype (original_type , defn .info , base )
2275- expanded_type = expand_self_type (
2276- original_node , expanded_type , fill_typevars (defn .info )
2277- )
2278- original_type = get_proper_type (expanded_type )
2236+ typ = get_proper_type (typ )
2237+ original_type = get_proper_type (original_type )
22792238
2280- if is_property (defn ):
2281- inner : FunctionLike | None
2282- if isinstance (typ , FunctionLike ):
2283- inner = typ
2284- else :
2285- inner = self .extract_callable_type (typ , context )
2286- if inner is not None :
2287- typ = inner
2288- typ = get_property_type (typ )
2289- if (
2290- isinstance (original_node , Var )
2291- and not original_node .is_final
2292- and (not original_node .is_property or original_node .is_settable_property )
2293- and isinstance (defn , Decorator )
2294- ):
2295- # We only give an error where no other similar errors will be given.
2296- if not isinstance (original_type , AnyType ):
2297- self .msg .fail (
2298- "Cannot override writeable attribute with read-only property" ,
2299- # Give an error on function line to match old behaviour.
2300- defn .func ,
2301- code = codes .OVERRIDE ,
2302- )
2239+ if (
2240+ is_property (defn )
2241+ and isinstance (original_node , Var )
2242+ and not original_node .is_final
2243+ and (not original_node .is_property or original_node .is_settable_property )
2244+ and isinstance (defn , Decorator )
2245+ ):
2246+ # We only give an error where no other similar errors will be given.
2247+ if not isinstance (original_type , AnyType ):
2248+ self .msg .fail (
2249+ "Cannot override writeable attribute with read-only property" ,
2250+ # Give an error on function line to match old behaviour.
2251+ defn .func ,
2252+ code = codes .OVERRIDE ,
2253+ )
23032254
23042255 if isinstance (original_type , AnyType ) or isinstance (typ , AnyType ):
23052256 pass
@@ -3412,7 +3363,7 @@ def get_variable_type_context(self, inferred: Var, rvalue: Expression) -> Type |
34123363 # For inference within class body, get supertype attribute as it would look on
34133364 # a class object for lambdas overriding methods, etc.
34143365 base_node = base .names [inferred .name ].node
3415- base_type , _ = self .lvalue_type_from_base (
3366+ base_type , _ = self .node_type_from_base (
34163367 inferred ,
34173368 base ,
34183369 is_class = is_method (base_node )
@@ -3523,7 +3474,7 @@ def check_compatibility_all_supers(self, lvalue: RefExpr, rvalue: Expression) ->
35233474 rvalue_type = self .expr_checker .accept (rvalue , lvalue_node .type )
35243475 actual_lvalue_type = lvalue_node .type
35253476 lvalue_node .type = rvalue_type
3526- lvalue_type , _ = self .lvalue_type_from_base (lvalue_node , lvalue_node .info )
3477+ lvalue_type , _ = self .node_type_from_base (lvalue_node , lvalue_node .info )
35273478 if lvalue_node .is_inferred and not lvalue_node .explicit_self_type :
35283479 lvalue_node .type = actual_lvalue_type
35293480
@@ -3542,7 +3493,7 @@ def check_compatibility_all_supers(self, lvalue: RefExpr, rvalue: Expression) ->
35423493 if is_private (lvalue_node .name ):
35433494 continue
35443495
3545- base_type , base_node = self .lvalue_type_from_base (lvalue_node , base )
3496+ base_type , base_node = self .node_type_from_base (lvalue_node , base )
35463497 custom_setter = is_custom_settable_property (base_node )
35473498 if isinstance (base_type , PartialType ):
35483499 base_type = None
@@ -3561,7 +3512,7 @@ def check_compatibility_all_supers(self, lvalue: RefExpr, rvalue: Expression) ->
35613512 # base classes are also incompatible
35623513 return
35633514 if lvalue_type and custom_setter :
3564- base_type , _ = self .lvalue_type_from_base (
3515+ base_type , _ = self .node_type_from_base (
35653516 lvalue_node , base , setter_type = True
35663517 )
35673518 # Setter type for a custom property must be ready if
@@ -3612,26 +3563,33 @@ def check_compatibility_super(
36123563 )
36133564 return ok
36143565
3615- def lvalue_type_from_base (
3616- self , expr_node : Var , base : TypeInfo , setter_type : bool = False , is_class : bool = False
3566+ def node_type_from_base (
3567+ self ,
3568+ node : SymbolNode ,
3569+ base : TypeInfo ,
3570+ * ,
3571+ setter_type : bool = False ,
3572+ is_class : bool = False ,
3573+ name_override : str | None = None ,
36173574 ) -> tuple [Type | None , SymbolNode | None ]:
3618- """Find a type for a variable name in base class.
3575+ """Find a type for a name in base class.
36193576
36203577 Return the type found and the corresponding node defining the name or None
36213578 for both if the name is not defined in base or the node type is not known (yet).
36223579 The type returned is already properly mapped/bound to the subclass.
36233580 If setter_type is True, return setter types for settable properties (otherwise the
36243581 getter type is returned).
36253582 """
3626- expr_name = expr_node .name
3627- base_var = base .names .get (expr_name )
3583+ name = name_override or node .name
3584+ base_node = base .names .get (name )
36283585
36293586 # TODO: defer current node if the superclass node is not ready.
36303587 if (
3631- not base_var
3632- or not base_var .type
3633- or isinstance (base_var .type , PartialType )
3634- and base_var .type .type is not None
3588+ not base_node
3589+ or isinstance (base_node .node , Var )
3590+ and not base_node .type
3591+ or isinstance (base_node .type , PartialType )
3592+ and base_node .type .type is not None
36353593 ):
36363594 return None , None
36373595
@@ -3645,9 +3603,9 @@ def lvalue_type_from_base(
36453603 mx = MemberContext (
36463604 is_lvalue = setter_type ,
36473605 is_super = False ,
3648- is_operator = mypy .checkexpr .is_operator_method (expr_name ),
3606+ is_operator = mypy .checkexpr .is_operator_method (name ),
36493607 original_type = self_type ,
3650- context = expr_node ,
3608+ context = node ,
36513609 chk = self ,
36523610 suppress_errors = True ,
36533611 )
@@ -3656,11 +3614,11 @@ def lvalue_type_from_base(
36563614 if is_class :
36573615 fallback = instance .type .metaclass_type or mx .named_type ("builtins.type" )
36583616 base_type = analyze_class_attribute_access (
3659- instance , expr_name , mx , mcs_fallback = fallback , override_info = base
3617+ instance , name , mx , mcs_fallback = fallback , override_info = base
36603618 )
36613619 else :
3662- base_type = analyze_instance_member_access (expr_name , instance , mx , base )
3663- return base_type , base_var .node
3620+ base_type = analyze_instance_member_access (name , instance , mx , base )
3621+ return base_type , base_node .node
36643622
36653623 def check_compatibility_classvar_super (
36663624 self , node : Var , base : TypeInfo , base_node : Node | None
@@ -8965,29 +8923,6 @@ def is_custom_settable_property(defn: SymbolNode | None) -> bool:
89658923 return not is_same_type (get_property_type (get_proper_type (var .type )), setter_type )
89668924
89678925
8968- def get_raw_setter_type (defn : OverloadedFuncDef | Var ) -> tuple [Type , bool ]:
8969- """Get an effective original setter type for a node.
8970-
8971- For a variable it is simply its type. For a property it is the type
8972- of the setter method (if not None), or the getter method (used as fallback
8973- for the plugin generated properties).
8974- Return the type and a flag indicating that we didn't fall back to getter.
8975- """
8976- if isinstance (defn , Var ):
8977- # This function should not be called if the var is not ready.
8978- assert defn .type is not None
8979- return defn .type , True
8980- first_item = defn .items [0 ]
8981- assert isinstance (first_item , Decorator )
8982- var = first_item .var
8983- # This function may be called on non-custom properties, so we need
8984- # to handle the situation when it is synthetic (plugin generated).
8985- if var .setter_type is not None :
8986- return var .setter_type , True
8987- assert var .type is not None
8988- return var .type , False
8989-
8990-
89918926def get_property_type (t : ProperType ) -> ProperType :
89928927 if isinstance (t , CallableType ):
89938928 return get_proper_type (t .ret_type )
0 commit comments