@@ -1362,7 +1362,7 @@ def check_func_def(
13621362 if typ .type_is :
13631363 arg_index = 0
13641364 # For methods and classmethods, we want the second parameter
1365- if ref_type is not None and ( not defn .is_static or defn . name == "__new__" ) :
1365+ if ref_type is not None and defn .has_self_or_cls_argument :
13661366 arg_index = 1
13671367 if arg_index < len (typ .arg_types ) and not is_subtype (
13681368 typ .type_is , typ .arg_types [arg_index ]
@@ -1382,7 +1382,7 @@ def check_func_def(
13821382 isinstance (defn , FuncDef )
13831383 and ref_type is not None
13841384 and i == 0
1385- and ( not defn .is_static or defn . name == "__new__" )
1385+ and defn .has_self_or_cls_argument
13861386 and typ .arg_kinds [0 ] not in [nodes .ARG_STAR , nodes .ARG_STAR2 ]
13871387 ):
13881388 if defn .is_class or defn .name == "__new__" :
@@ -4400,9 +4400,9 @@ def set_inferred_type(self, var: Var, lvalue: Lvalue, type: Type) -> None:
44004400 refers to the variable (lvalue). If var is None, do nothing.
44014401 """
44024402 if var and not self .current_node_deferred :
4403- # TODO: should we also set 'is_ready = True' here?
44044403 var .type = type
44054404 var .is_inferred = True
4405+ var .is_ready = True
44064406 if var not in self .var_decl_frames :
44074407 # Used for the hack to improve optional type inference in conditionals
44084408 self .var_decl_frames [var ] = {frame .id for frame in self .binder .frames }
@@ -4412,9 +4412,23 @@ def set_inferred_type(self, var: Var, lvalue: Lvalue, type: Type) -> None:
44124412 self .inferred_attribute_types [lvalue .def_var ] = type
44134413 self .store_type (lvalue , type )
44144414 p_type = get_proper_type (type )
4415- if isinstance (p_type , CallableType ) and is_node_static (p_type .definition ):
4416- # TODO: handle aliases to class methods (similarly).
4417- var .is_staticmethod = True
4415+ definition = None
4416+ if isinstance (p_type , CallableType ):
4417+ definition = p_type .definition
4418+ elif isinstance (p_type , Overloaded ):
4419+ # Randomly select first item, if items are different, there will
4420+ # be an error during semantic analysis.
4421+ definition = p_type .items [0 ].definition
4422+ if definition :
4423+ if is_node_static (definition ):
4424+ var .is_staticmethod = True
4425+ elif is_classmethod_node (definition ):
4426+ var .is_classmethod = True
4427+ elif is_property (definition ):
4428+ var .is_property = True
4429+ if isinstance (p_type , Overloaded ):
4430+ # TODO: in theory we can have a property with a deleter only.
4431+ var .is_settable_property = True
44184432
44194433 def set_inference_error_fallback_type (self , var : Var , lvalue : Lvalue , type : Type ) -> None :
44204434 """Store best known type for variable if type inference failed.
@@ -8531,15 +8545,21 @@ def visit_type_alias_type(self, t: TypeAliasType) -> Type:
85318545 return t .copy_modified (args = [a .accept (self ) for a in t .args ])
85328546
85338547
8548+ def is_classmethod_node (node : Node | None ) -> bool | None :
8549+ """Find out if a node describes a classmethod."""
8550+ if isinstance (node , FuncDef ):
8551+ return node .is_class
8552+ if isinstance (node , Var ):
8553+ return node .is_classmethod
8554+ return None
8555+
8556+
85348557def is_node_static (node : Node | None ) -> bool | None :
85358558 """Find out if a node describes a static function method."""
8536-
85378559 if isinstance (node , FuncDef ):
85388560 return node .is_static
8539-
85408561 if isinstance (node , Var ):
85418562 return node .is_staticmethod
8542-
85438563 return None
85448564
85458565
@@ -8786,6 +8806,8 @@ def is_static(func: FuncBase | Decorator) -> bool:
87868806
87878807
87888808def is_property (defn : SymbolNode ) -> bool :
8809+ if isinstance (defn , FuncDef ):
8810+ return defn .is_property
87898811 if isinstance (defn , Decorator ):
87908812 return defn .func .is_property
87918813 if isinstance (defn , OverloadedFuncDef ):
0 commit comments