@@ -2431,6 +2431,10 @@ def has_member(self, typ: Type, member: str) -> bool:
2431
2431
"""Does type have member with the given name?"""
2432
2432
# TODO: refactor this to use checkmember.analyze_member_access, otherwise
2433
2433
# these two should be carefully kept in sync.
2434
+ if isinstance (typ , TypeVarType ):
2435
+ typ = typ .upper_bound
2436
+ if isinstance (typ , TupleType ):
2437
+ typ = typ .fallback
2434
2438
if isinstance (typ , Instance ):
2435
2439
return typ .type .has_readable_member (member )
2436
2440
if isinstance (typ , CallableType ) and typ .is_type_obj ():
@@ -2440,14 +2444,17 @@ def has_member(self, typ: Type, member: str) -> bool:
2440
2444
elif isinstance (typ , UnionType ):
2441
2445
result = all (self .has_member (x , member ) for x in typ .relevant_items ())
2442
2446
return result
2443
- elif isinstance (typ , TupleType ):
2444
- return self .has_member (typ .fallback , member )
2445
2447
elif isinstance (typ , TypeType ):
2446
2448
# Type[Union[X, ...]] is always normalized to Union[Type[X], ...],
2447
2449
# so we don't need to care about unions here.
2448
- if isinstance (typ .item , Instance ) and typ .item .type .metaclass_type is not None :
2449
- return self .has_member (typ .item .type .metaclass_type , member )
2450
- if isinstance (typ .item , AnyType ):
2450
+ item = typ .item
2451
+ if isinstance (item , TypeVarType ):
2452
+ item = item .upper_bound
2453
+ if isinstance (item , TupleType ):
2454
+ item = item .fallback
2455
+ if isinstance (item , Instance ) and item .type .metaclass_type is not None :
2456
+ return self .has_member (item .type .metaclass_type , member )
2457
+ if isinstance (item , AnyType ):
2451
2458
return True
2452
2459
return False
2453
2460
else :
0 commit comments