126126 validate_instance ,
127127)
128128from mypy .typeops import (
129+ bind_self ,
129130 callable_type ,
130131 custom_special_method ,
131132 erase_to_union_or_bound ,
@@ -355,10 +356,7 @@ def visit_name_expr(self, e: NameExpr) -> Type:
355356 self .chk .module_refs .update (extract_refexpr_names (e ))
356357 result = self .analyze_ref_expr (e )
357358 narrowed = self .narrow_type_from_binder (e , result )
358- if isinstance (e .node , TypeInfo ):
359- self .chk .check_deprecated (e .node , e )
360- elif isinstance (typ := get_proper_type (narrowed ), (CallableType , Overloaded )):
361- self .chk .check_deprecated (typ , e )
359+ self .chk .check_deprecated (e .node , e )
362360 return narrowed
363361
364362 def analyze_ref_expr (self , e : RefExpr , lvalue : bool = False ) -> Type :
@@ -1480,8 +1478,10 @@ def check_call_expr_with_callee_type(
14801478 object_type = object_type ,
14811479 )
14821480 proper_callee = get_proper_type (callee_type )
1483- if isinstance (proper_callee , (CallableType , Overloaded )):
1484- self .chk .check_deprecated (proper_callee , e )
1481+ if isinstance (e .callee , NameExpr ) and isinstance (e .callee .node , OverloadedFuncDef ):
1482+ for item in e .callee .node .items :
1483+ if isinstance (item , Decorator ) and (item .func .type == callee_type ):
1484+ self .chk .check_deprecated (item .func , e )
14851485 if isinstance (e .callee , RefExpr ) and isinstance (proper_callee , CallableType ):
14861486 # Cache it for find_isinstance_check()
14871487 if proper_callee .type_guard is not None :
@@ -3260,10 +3260,7 @@ def visit_member_expr(self, e: MemberExpr, is_lvalue: bool = False) -> Type:
32603260 self .chk .module_refs .update (extract_refexpr_names (e ))
32613261 result = self .analyze_ordinary_member_access (e , is_lvalue )
32623262 narrowed = self .narrow_type_from_binder (e , result )
3263- if isinstance (e .node , TypeInfo ):
3264- self .chk .warn_deprecated (e .node , e )
3265- elif isinstance (typ := get_proper_type (narrowed ), (CallableType , Overloaded )):
3266- self .chk .warn_deprecated (typ , e )
3263+ self .chk .warn_deprecated (e .node , e )
32673264 return narrowed
32683265
32693266 def analyze_ordinary_member_access (self , e : MemberExpr , is_lvalue : bool ) -> Type :
@@ -3489,8 +3486,6 @@ def visit_op_expr(self, e: OpExpr) -> Type:
34893486 else :
34903487 assert_never (use_reverse )
34913488 e .method_type = method_type
3492- if isinstance (mt := get_proper_type (method_type ), (CallableType , Overloaded )):
3493- self .chk .check_deprecated (mt , e )
34943489 return result
34953490 else :
34963491 raise RuntimeError (f"Unknown operator { e .op } " )
@@ -3807,8 +3802,6 @@ def check_method_call_by_name(
38073802 chk = self .chk ,
38083803 in_literal_context = self .is_literal_context (),
38093804 )
3810- if isinstance (mt := get_proper_type (method_type ), (CallableType , Overloaded )):
3811- self .chk .warn_deprecated (mt , context )
38123805 return self .check_method_call (method , base_type , method_type , args , arg_kinds , context )
38133806
38143807 def check_union_method_call_by_name (
@@ -3957,7 +3950,7 @@ def lookup_definer(typ: Instance, attr_name: str) -> str | None:
39573950 # This is the case even if the __add__ method is completely missing and the __radd__
39583951 # method is defined.
39593952
3960- variants_raw = [(left_op , left_type , right_expr )]
3953+ variants_raw = [(op_name , left_op , left_type , right_expr )]
39613954 elif (
39623955 is_subtype (right_type , left_type )
39633956 and isinstance (left_type , Instance )
@@ -3978,19 +3971,25 @@ def lookup_definer(typ: Instance, attr_name: str) -> str | None:
39783971 # As a special case, the alt_promote check makes sure that we don't use the
39793972 # __radd__ method of int if the LHS is a native int type.
39803973
3981- variants_raw = [(right_op , right_type , left_expr ), (left_op , left_type , right_expr )]
3974+ variants_raw = [
3975+ (rev_op_name , right_op , right_type , left_expr ),
3976+ (op_name , left_op , left_type , right_expr ),
3977+ ]
39823978 else :
39833979 # In all other cases, we do the usual thing and call __add__ first and
39843980 # __radd__ second when doing "A() + B()".
39853981
3986- variants_raw = [(left_op , left_type , right_expr ), (right_op , right_type , left_expr )]
3982+ variants_raw = [
3983+ (op_name , left_op , left_type , right_expr ),
3984+ (rev_op_name , right_op , right_type , left_expr ),
3985+ ]
39873986
39883987 # STEP 3:
39893988 # We now filter out all non-existent operators. The 'variants' list contains
39903989 # all operator methods that are actually present, in the order that Python
39913990 # attempts to invoke them.
39923991
3993- variants = [(op , obj , arg ) for (op , obj , arg ) in variants_raw if op is not None ]
3992+ variants = [(na , op , obj , arg ) for (na , op , obj , arg ) in variants_raw if op is not None ]
39943993
39953994 # STEP 4:
39963995 # We now try invoking each one. If an operation succeeds, end early and return
@@ -3999,13 +3998,24 @@ def lookup_definer(typ: Instance, attr_name: str) -> str | None:
39993998
40003999 errors = []
40014000 results = []
4002- for method , obj , arg in variants :
4001+ for name , method , obj , arg in variants :
40034002 with self .msg .filter_errors (save_filtered_errors = True ) as local_errors :
40044003 result = self .check_method_call (op_name , obj , method , [arg ], [ARG_POS ], context )
40054004 if local_errors .has_new_errors ():
40064005 errors .append (local_errors .filtered_errors ())
40074006 results .append (result )
40084007 else :
4008+ if (
4009+ isinstance (obj , Instance )
4010+ and isinstance (defn := obj .type .get_method (name ), OverloadedFuncDef )
4011+ ):
4012+ for item in defn .items :
4013+ if (
4014+ isinstance (item , Decorator )
4015+ and isinstance (typ := item .func .type , CallableType )
4016+ and bind_self (typ ) == result [1 ]
4017+ ):
4018+ self .chk .check_deprecated (item .func , context )
40094019 return result
40104020
40114021 # We finish invoking above operators and no early return happens. Therefore,
0 commit comments