59
59
from mypy .visitor import ExpressionVisitor
60
60
from mypy .plugin import Plugin , MethodContext , MethodSigContext , FunctionContext
61
61
from mypy .typeanal import make_optional_type
62
+ from mypy .typeops import tuple_fallback
62
63
63
64
# Type of callback user for checking individual function arguments. See
64
65
# check_args() below for details.
@@ -347,7 +348,7 @@ def method_fullname(self, object_type: Type, method_name: str) -> Optional[str]:
347
348
info = object_type .fallback .type .get_containing_type_info (method_name )
348
349
type_name = info .fullname () if info is not None else None
349
350
elif isinstance (object_type , TupleType ):
350
- type_name = object_type . fallback .type .fullname ()
351
+ type_name = tuple_fallback ( object_type ) .type .fullname ()
351
352
352
353
if type_name is not None :
353
354
return '{}.{}' .format (type_name , method_name )
@@ -722,7 +723,7 @@ def check_call(self,
722
723
return self .check_call (item , args , arg_kinds , context , arg_names ,
723
724
callable_node , arg_messages )
724
725
elif isinstance (callee , TupleType ):
725
- return self .check_call (callee . fallback , args , arg_kinds , context ,
726
+ return self .check_call (tuple_fallback ( callee ) , args , arg_kinds , context ,
726
727
arg_names , callable_node , arg_messages , callable_name ,
727
728
object_type )
728
729
else :
@@ -835,8 +836,9 @@ def analyze_type_type_callee(self, item: Type, context: Context) -> Type:
835
836
if callee :
836
837
return callee
837
838
# We support Type of namedtuples but not of tuples in general
838
- if isinstance (item , TupleType ) and item .fallback .type .fullname () != 'builtins.tuple' :
839
- return self .analyze_type_type_callee (item .fallback , context )
839
+ if (isinstance (item , TupleType )
840
+ and tuple_fallback (item ).type .fullname () != 'builtins.tuple' ):
841
+ return self .analyze_type_type_callee (tuple_fallback (item ), context )
840
842
841
843
self .msg .unsupported_type_type (item , context )
842
844
return AnyType (TypeOfAny .from_error )
@@ -2666,8 +2668,8 @@ class LongName(Generic[T]): ...
2666
2668
return self .apply_type_arguments_to_callable (tp , item .args , ctx )
2667
2669
elif (isinstance (item , TupleType ) and
2668
2670
# Tuple[str, int]() fails at runtime, only named tuples and subclasses work.
2669
- item . fallback .type .fullname () != 'builtins.tuple' ):
2670
- return type_object_type (item . fallback .type , self .named_type )
2671
+ tuple_fallback ( item ) .type .fullname () != 'builtins.tuple' ):
2672
+ return type_object_type (tuple_fallback ( item ) .type , self .named_type )
2671
2673
elif isinstance (item , AnyType ):
2672
2674
return AnyType (TypeOfAny .from_another_any , source_any = item )
2673
2675
else :
@@ -2785,7 +2787,8 @@ def visit_tuple_expr(self, e: TupleExpr) -> Type:
2785
2787
tt = self .accept (item , type_context_items [j ])
2786
2788
j += 1
2787
2789
items .append (tt )
2788
- fallback_item = join .join_type_list (items )
2790
+ # This is a partial fallback item type. A precise type will be calculated on demand.
2791
+ fallback_item = AnyType (TypeOfAny .special_form )
2789
2792
return TupleType (items , self .chk .named_generic_type ('builtins.tuple' , [fallback_item ]))
2790
2793
2791
2794
def visit_dict_expr (self , e : DictExpr ) -> Type :
@@ -2973,7 +2976,8 @@ def check_super_arguments(self, e: SuperExpr) -> None:
2973
2976
# Could be anything.
2974
2977
return
2975
2978
if isinstance (item , TupleType ):
2976
- item = item .fallback # Handle named tuples and other Tuple[...] subclasses.
2979
+ # Handle named tuples and other Tuple[...] subclasses.
2980
+ item = tuple_fallback (item )
2977
2981
if not isinstance (item , Instance ):
2978
2982
# A complicated type object type. Too tricky, give up.
2979
2983
# TODO: Do something more clever here.
@@ -2997,7 +3001,7 @@ def check_super_arguments(self, e: SuperExpr) -> None:
2997
3001
return
2998
3002
if isinstance (instance_type , TupleType ):
2999
3003
# Needed for named tuples and other Tuple[...] subclasses.
3000
- instance_type = instance_type . fallback
3004
+ instance_type = tuple_fallback ( instance_type )
3001
3005
if type_info not in instance_type .type .mro :
3002
3006
self .chk .fail (message_registry .SUPER_ARG_2_NOT_INSTANCE_OF_ARG_1 , e )
3003
3007
elif isinstance (instance_type , TypeType ) or (isinstance (instance_type , FunctionLike )
@@ -3287,7 +3291,9 @@ def has_member(self, typ: Type, member: str) -> bool:
3287
3291
# these two should be carefully kept in sync.
3288
3292
if isinstance (typ , TypeVarType ):
3289
3293
typ = typ .upper_bound
3290
- if isinstance (typ , (TupleType , LiteralType )):
3294
+ if isinstance (typ , TupleType ):
3295
+ typ = tuple_fallback (typ )
3296
+ if isinstance (typ , LiteralType ):
3291
3297
typ = typ .fallback
3292
3298
if isinstance (typ , Instance ):
3293
3299
return typ .type .has_readable_member (member )
@@ -3305,7 +3311,7 @@ def has_member(self, typ: Type, member: str) -> bool:
3305
3311
if isinstance (item , TypeVarType ):
3306
3312
item = item .upper_bound
3307
3313
if isinstance (item , TupleType ):
3308
- item = item . fallback
3314
+ item = tuple_fallback ( item )
3309
3315
if isinstance (item , Instance ) and item .type .metaclass_type is not None :
3310
3316
return self .has_member (item .type .metaclass_type , member )
3311
3317
if isinstance (item , AnyType ):
@@ -3645,7 +3651,7 @@ def is_typetype_like(typ: Type) -> bool:
3645
3651
if isinstance (actual , Overloaded ):
3646
3652
actual = actual .items ()[0 ].fallback
3647
3653
if isinstance (actual , TupleType ):
3648
- actual = actual . fallback
3654
+ actual = tuple_fallback ( actual )
3649
3655
if isinstance (actual , Instance ) and formal .type in actual .type .mro :
3650
3656
# Try performing a quick check as an optimization
3651
3657
return True
0 commit comments