5757 LiteralType ,
5858 NoneType ,
5959 Overloaded ,
60+ Parameters ,
6061 ParamSpecType ,
6162 PartialType ,
6263 ProperType ,
@@ -782,6 +783,33 @@ def analyze_var(
782783 else :
783784 call_type = typ
784785
786+ if isinstance (call_type , Instance ) and any (
787+ isinstance (arg , Parameters ) for arg in call_type .args
788+ ):
789+ args : list [Type ] = []
790+ for arg in call_type .args :
791+ if not isinstance (arg , Parameters ):
792+ args .append (arg )
793+ continue
794+ c = callable_type_from_parameters (arg , mx .chk .named_type ("builtins.function" ))
795+ if not var .is_staticmethod :
796+ functype : FunctionLike = c
797+ dispatched_type = meet .meet_types (mx .original_type , itype )
798+ signature = freshen_all_functions_type_vars (functype )
799+ bound = get_proper_type (expand_self_type (var , signature , mx .original_type ))
800+ assert isinstance (bound , FunctionLike )
801+ signature = bound
802+ signature = check_self_arg (
803+ signature , dispatched_type , var .is_classmethod , mx .context , name , mx .msg
804+ )
805+ signature = bind_self (signature , mx .self_type , var .is_classmethod )
806+ expanded_signature = expand_type_by_instance (signature , itype )
807+ freeze_all_type_vars (expanded_signature )
808+ assert isinstance (expanded_signature , CallableType )
809+ arg = update_parameters_from_signature (arg , expanded_signature )
810+ args .append (arg )
811+ call_type = call_type .copy_modified (args = args )
812+ result = call_type
785813 if isinstance (call_type , FunctionLike ) and not call_type .is_type_obj ():
786814 if mx .is_lvalue :
787815 if var .is_property :
@@ -793,7 +821,7 @@ def analyze_var(
793821 if not var .is_staticmethod :
794822 # Class-level function objects and classmethods become bound methods:
795823 # the former to the instance, the latter to the class.
796- functype : FunctionLike = call_type
824+ functype = call_type
797825 # Use meet to narrow original_type to the dispatched type.
798826 # For example, assume
799827 # * A.f: Callable[[A1], None] where A1 <: A (maybe A1 == A)
@@ -1094,6 +1122,30 @@ def analyze_class_attribute_access(
10941122 isinstance (node .node , FuncBase ) and node .node .is_static
10951123 )
10961124 t = get_proper_type (t )
1125+ if isinstance (t , Instance ) and any (isinstance (arg , Parameters ) for arg in t .args ):
1126+ args : list [Type ] = []
1127+ for arg in t .args :
1128+ if not isinstance (arg , Parameters ):
1129+ args .append (arg )
1130+ continue
1131+ c : FunctionLike = callable_type_from_parameters (
1132+ arg , mx .chk .named_type ("builtins.function" )
1133+ )
1134+ if is_classmethod :
1135+ c = check_self_arg (c , mx .self_type , False , mx .context , name , mx .msg )
1136+ res = add_class_tvars (
1137+ c ,
1138+ isuper ,
1139+ is_classmethod ,
1140+ is_staticmethod ,
1141+ mx .self_type ,
1142+ original_vars = original_vars ,
1143+ )
1144+ signature = get_proper_type (res )
1145+ assert isinstance (signature , CallableType )
1146+ arg = update_parameters_from_signature (arg , signature )
1147+ args .append (arg )
1148+ t = t .copy_modified (args = args )
10971149 if isinstance (t , FunctionLike ) and is_classmethod :
10981150 t = check_self_arg (t , mx .self_type , False , mx .context , name , mx .msg )
10991151 result = add_class_tvars (
@@ -1392,3 +1444,30 @@ def is_valid_constructor(n: SymbolNode | None) -> bool:
13921444 if isinstance (n , Decorator ):
13931445 return isinstance (get_proper_type (n .type ), FunctionLike )
13941446 return False
1447+
1448+
1449+ def callable_type_from_parameters (
1450+ param : Parameters , fallback : Instance , ret_type : Type | None = None
1451+ ) -> CallableType :
1452+ """Create CallableType from Parameters."""
1453+ return CallableType (
1454+ arg_types = param .arg_types ,
1455+ arg_kinds = param .arg_kinds ,
1456+ arg_names = param .arg_names ,
1457+ ret_type = ret_type if ret_type is not None else NoneType (),
1458+ fallback = fallback ,
1459+ variables = param .variables ,
1460+ imprecise_arg_kinds = param .imprecise_arg_kinds ,
1461+ )
1462+
1463+
1464+ def update_parameters_from_signature (param : Parameters , signature : CallableType ) -> Parameters :
1465+ """Update Parameters from signature."""
1466+ return param .copy_modified (
1467+ arg_types = signature .arg_types ,
1468+ arg_kinds = signature .arg_kinds ,
1469+ arg_names = signature .arg_names ,
1470+ is_ellipsis_args = signature .is_ellipsis_args ,
1471+ variables = signature .variables ,
1472+ imprecise_arg_kinds = signature .imprecise_arg_kinds ,
1473+ )
0 commit comments