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