@@ -703,6 +703,12 @@ def _visit_overloaded_func_def(self, defn: OverloadedFuncDef) -> None:
703703 # TODO: keep precise type for callables with tricky but valid signatures.
704704 setter_type = fallback_setter_type
705705 defn .items [0 ].var .setter_type = setter_type
706+ if isinstance (defn .type , Overloaded ):
707+ # Update legacy property type for decorated properties.
708+ getter_type = self .extract_callable_type (defn .items [0 ].var .type , defn )
709+ if getter_type is not None :
710+ getter_type .definition = defn .items [0 ]
711+ defn .type .items [0 ] = getter_type
706712 for i , fdef in enumerate (defn .items ):
707713 assert isinstance (fdef , Decorator )
708714 if defn .is_property :
@@ -730,7 +736,7 @@ def _visit_overloaded_func_def(self, defn: OverloadedFuncDef) -> None:
730736 assert isinstance (item , Decorator )
731737 item_type = self .extract_callable_type (item .var .type , item )
732738 if item_type is not None :
733- item_type .definition = item . func
739+ item_type .definition = item
734740 item_types .append (item_type )
735741 if item_types :
736742 defn .type = Overloaded (item_types )
@@ -3509,6 +3515,7 @@ def check_compatibility_all_supers(self, lvalue: RefExpr, rvalue: Expression) ->
35093515 continue
35103516
35113517 base_type , base_node = self .node_type_from_base (lvalue_node .name , base , lvalue )
3518+ # TODO: if the r.h.s. is a descriptor, we should check setter override as well.
35123519 custom_setter = is_custom_settable_property (base_node )
35133520 if isinstance (base_type , PartialType ):
35143521 base_type = None
@@ -4494,6 +4501,8 @@ def set_inferred_type(self, var: Var, lvalue: Lvalue, type: Type) -> None:
44944501 if isinstance (p_type , Overloaded ):
44954502 # TODO: in theory we can have a property with a deleter only.
44964503 var .is_settable_property = True
4504+ assert isinstance (definition , Decorator )
4505+ var .setter_type = definition .var .setter_type
44974506
44984507 def set_inference_error_fallback_type (self , var : Var , lvalue : Lvalue , type : Type ) -> None :
44994508 """Store best known type for variable if type inference failed.
@@ -5356,6 +5365,8 @@ def visit_decorator_inner(
53565365 self .check_untyped_after_decorator (sig , e .func )
53575366 self .require_correct_self_argument (sig , e .func )
53585367 sig = set_callable_name (sig , e .func )
5368+ if isinstance (sig , CallableType ):
5369+ sig .definition = e
53595370 e .var .type = sig
53605371 e .var .is_ready = True
53615372 if e .func .is_property :
@@ -8651,17 +8662,21 @@ def visit_type_alias_type(self, t: TypeAliasType) -> Type:
86518662 return t .copy_modified (args = [a .accept (self ) for a in t .args ])
86528663
86538664
8654- def is_classmethod_node (node : Node | None ) -> bool | None :
8665+ def is_classmethod_node (node : SymbolNode | None ) -> bool | None :
86558666 """Find out if a node describes a classmethod."""
8667+ if isinstance (node , Decorator ):
8668+ node = node .func
86568669 if isinstance (node , FuncDef ):
86578670 return node .is_class
86588671 if isinstance (node , Var ):
86598672 return node .is_classmethod
86608673 return None
86618674
86628675
8663- def is_node_static (node : Node | None ) -> bool | None :
8676+ def is_node_static (node : SymbolNode | None ) -> bool | None :
86648677 """Find out if a node describes a static function method."""
8678+ if isinstance (node , Decorator ):
8679+ node = node .func
86658680 if isinstance (node , FuncDef ):
86668681 return node .is_static
86678682 if isinstance (node , Var ):
0 commit comments