@@ -371,7 +371,26 @@ def validate_super_call(node: FuncBase, mx: MemberContext) -> None:
371371def analyze_type_callable_member_access (name : str , typ : FunctionLike , mx : MemberContext ) -> Type :
372372 # Class attribute.
373373 # TODO super?
374- ret_type = typ .items [0 ].ret_type
374+ item = typ .items [0 ]
375+ ret_type = item .ret_type
376+
377+ # The following is a hack. mypy often represents types as CallableType, where the signature of
378+ # CallableType is determined by __new__ or __init__ of the type (this logic is in
379+ # type_object_type). Then if we ever need the TypeInfo or an instance of the type, we fish
380+ # around for the return type in CallableType.type_object. Unfortunately, this is incorrect if
381+ # __new__ returns an unrelated type, but we can kind of salvage things by fishing around in
382+ # CallableType.bound_args
383+ self_type : Type = typ
384+ if len (item .bound_args ) == 1 and item .bound_args [0 ]:
385+ bound_arg = get_proper_type (item .bound_args [0 ])
386+ if isinstance (bound_arg , Instance ) and isinstance (ret_type , Instance ):
387+ # Unfortunately, generic arguments have already been determined for us. We need these,
388+ # see e.g. testGenericClassMethodUnboundOnClass. So just copy them over to our type.
389+ # This does the wrong thing with custom __new__, see testNewReturnType15, but is
390+ # a lesser evil.
391+ ret_type = bound_arg .copy_modified (args = ret_type .args )
392+ self_type = TypeType (ret_type )
393+
375394 assert isinstance (ret_type , ProperType )
376395 if isinstance (ret_type , TupleType ):
377396 ret_type = tuple_fallback (ret_type )
@@ -394,7 +413,11 @@ def analyze_type_callable_member_access(name: str, typ: FunctionLike, mx: Member
394413 # See https://github.com/python/mypy/pull/1787 for more info.
395414 # TODO: do not rely on same type variables being present in all constructor overloads.
396415 result = analyze_class_attribute_access (
397- ret_type , name , mx , original_vars = typ .items [0 ].variables , mcs_fallback = typ .fallback
416+ ret_type ,
417+ name ,
418+ mx .copy_modified (self_type = self_type ),
419+ original_vars = typ .items [0 ].variables ,
420+ mcs_fallback = typ .fallback ,
398421 )
399422 if result :
400423 return result
0 commit comments