@@ -4568,117 +4568,15 @@ def check_member_assignment(
45684568 lvalue , is_lvalue = False
45694569 )
45704570
4571- < << << << HEAD
4572- if not isinstance (attribute_type , Instance ):
4573- # TODO: support __set__() for union types.
4574- rvalue_type = self .check_simple_assignment (attribute_type , rvalue , context )
4575- return rvalue_type , attribute_type , use_binder
4576-
4577- mx = MemberContext (
4578- is_lvalue = False ,
4579- is_super = False ,
4580- is_operator = False ,
4581- original_type = instance_type ,
4582- context = context ,
4583- self_type = None ,
4584- msg = self .msg ,
4585- chk = self ,
4586- )
4587- get_type = analyze_descriptor_access (attribute_type , mx , assignment = True )
4588- if not attribute_type .type .has_readable_member ("__set__" ):
4589- # If there is no __set__, we type-check that the assigned value matches
4590- # the return type of __get__. This doesn't match the python semantics,
4591- # (which allow you to override the descriptor with any value), but preserves
4592- # the type of accessing the attribute (even after the override).
4593- rvalue_type = self .check_simple_assignment (get_type , rvalue , context )
4594- return rvalue_type , get_type , use_binder
4595-
4596- dunder_set = attribute_type .type .get_method ("__set__" )
4597- if dunder_set is None :
4598- self .fail (
4599- message_registry .DESCRIPTOR_SET_NOT_CALLABLE .format (
4600- attribute_type .str_with_options (self .options )
4601- ),
4602- context ,
4603- )
4604- return AnyType (TypeOfAny .from_error ), get_type , False
4605-
4606- bound_method = analyze_decorator_or_funcbase_access (
4607- defn = dunder_set ,
4608- itype = attribute_type ,
4609- name = "__set__" ,
4610- mx = mx .copy_modified (self_type = attribute_type ),
4611- )
4612- typ = map_instance_to_supertype (attribute_type , dunder_set .info )
4613- dunder_set_type = expand_type_by_instance (bound_method , typ )
4614-
4615- callable_name = self .expr_checker .method_fullname (attribute_type , "__set__" )
4616- dunder_set_type = self .expr_checker .transform_callee_type (
4617- callable_name ,
4618- dunder_set_type ,
4619- [TempNode (instance_type , context = context ), rvalue ],
4620- [nodes .ARG_POS , nodes .ARG_POS ],
4621- context ,
4622- object_type = attribute_type ,
4623- )
4624-
4625- # For non-overloaded setters, the result should be type-checked like a regular assignment.
4626- # Hence, we first only try to infer the type by using the rvalue as type context.
4627- type_context = rvalue
4628- with self .msg .filter_errors ():
4629- _ , inferred_dunder_set_type = self .expr_checker .check_call (
4630- dunder_set_type ,
4631- [TempNode (instance_type , context = context ), type_context ],
4632- [nodes .ARG_POS , nodes .ARG_POS ],
4633- context ,
4634- object_type = attribute_type ,
4635- callable_name = callable_name ,
4636- )
4637-
4638- # And now we in fact type check the call, to show errors related to wrong arguments
4639- # count, etc., replacing the type context for non-overloaded setters only.
4640- inferred_dunder_set_type = get_proper_type (inferred_dunder_set_type )
4641- if isinstance (inferred_dunder_set_type , CallableType ):
4642- type_context = TempNode (AnyType (TypeOfAny .special_form ), context = context )
4643- self .expr_checker .check_call (
4644- dunder_set_type ,
4645- [TempNode (instance_type , context = context ), type_context ],
4646- [nodes .ARG_POS , nodes .ARG_POS ],
4647- context ,
4648- object_type = attribute_type ,
4649- callable_name = callable_name ,
4650- )
4651-
4652- # Search for possible deprecations:
4653- mx .chk .check_deprecated (dunder_set , mx .context )
4654- mx .chk .warn_deprecated_overload_item (
4655- dunder_set , mx .context , target = inferred_dunder_set_type , selftype = attribute_type
4656- )
4657-
4658- # In the following cases, a message already will have been recorded in check_call.
4659- if (not isinstance (inferred_dunder_set_type , CallableType )) or (
4660- len (inferred_dunder_set_type .arg_types ) < 2
4661- ):
4662- return AnyType (TypeOfAny .from_error ), get_type , False
4663-
4664- set_type = inferred_dunder_set_type .arg_types [1 ]
4665- == == == =
4666- >> >> >> > df9ddfcac (Consolidate descriptor handling in checkmember .py (#18831))
46674571 # Special case: if the rvalue_type is a subtype of both '__get__' and '__set__' types,
46684572 # and '__get__' type is narrower than '__set__', then we invoke the binder to narrow type
46694573 # by this assignment. Technically, this is not safe, but in practice this is
46704574 # what a user expects.
4671- << << << < HEAD
4672- rvalue_type = self .check_simple_assignment (set_type , rvalue , context )
4673- infer = is_subtype (rvalue_type , get_type ) and is_subtype (get_type , set_type )
4674- return rvalue_type if infer else set_type , get_type , infer
4675- == == == =
4676- rvalue_type , _ = self .check_simple_assignment (attribute_type , rvalue , context )
4575+ rvalue_type = self .check_simple_assignment (attribute_type , rvalue , context )
46774576 infer = is_subtype (rvalue_type , get_lvalue_type ) and is_subtype (
46784577 get_lvalue_type , attribute_type
46794578 )
46804579 return rvalue_type if infer else attribute_type , attribute_type , infer
4681- >> > >> >> df9ddfcac (Consolidate descriptor handling in checkmember .py (#18831))
46824580
46834581 def check_indexed_assignment (
46844582 self , lvalue : IndexExpr , rvalue : Expression , context : Context
0 commit comments