5959from mypy .visitor import ExpressionVisitor
6060from mypy .plugin import Plugin , MethodContext , MethodSigContext , FunctionContext
6161from mypy .typeanal import make_optional_type
62+ from mypy .typeops import tuple_fallback
6263
6364# Type of callback user for checking individual function arguments. See
6465# check_args() below for details.
@@ -347,7 +348,7 @@ def method_fullname(self, object_type: Type, method_name: str) -> Optional[str]:
347348 info = object_type .fallback .type .get_containing_type_info (method_name )
348349 type_name = info .fullname () if info is not None else None
349350 elif isinstance (object_type , TupleType ):
350- type_name = object_type . fallback .type .fullname ()
351+ type_name = tuple_fallback ( object_type ) .type .fullname ()
351352
352353 if type_name is not None :
353354 return '{}.{}' .format (type_name , method_name )
@@ -722,7 +723,7 @@ def check_call(self,
722723 return self .check_call (item , args , arg_kinds , context , arg_names ,
723724 callable_node , arg_messages )
724725 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 ,
726727 arg_names , callable_node , arg_messages , callable_name ,
727728 object_type )
728729 else :
@@ -835,8 +836,9 @@ def analyze_type_type_callee(self, item: Type, context: Context) -> Type:
835836 if callee :
836837 return callee
837838 # 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 )
840842
841843 self .msg .unsupported_type_type (item , context )
842844 return AnyType (TypeOfAny .from_error )
@@ -2666,8 +2668,8 @@ class LongName(Generic[T]): ...
26662668 return self .apply_type_arguments_to_callable (tp , item .args , ctx )
26672669 elif (isinstance (item , TupleType ) and
26682670 # 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 )
26712673 elif isinstance (item , AnyType ):
26722674 return AnyType (TypeOfAny .from_another_any , source_any = item )
26732675 else :
@@ -2785,7 +2787,8 @@ def visit_tuple_expr(self, e: TupleExpr) -> Type:
27852787 tt = self .accept (item , type_context_items [j ])
27862788 j += 1
27872789 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 )
27892792 return TupleType (items , self .chk .named_generic_type ('builtins.tuple' , [fallback_item ]))
27902793
27912794 def visit_dict_expr (self , e : DictExpr ) -> Type :
@@ -2973,7 +2976,8 @@ def check_super_arguments(self, e: SuperExpr) -> None:
29732976 # Could be anything.
29742977 return
29752978 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 )
29772981 if not isinstance (item , Instance ):
29782982 # A complicated type object type. Too tricky, give up.
29792983 # TODO: Do something more clever here.
@@ -2997,7 +3001,7 @@ def check_super_arguments(self, e: SuperExpr) -> None:
29973001 return
29983002 if isinstance (instance_type , TupleType ):
29993003 # Needed for named tuples and other Tuple[...] subclasses.
3000- instance_type = instance_type . fallback
3004+ instance_type = tuple_fallback ( instance_type )
30013005 if type_info not in instance_type .type .mro :
30023006 self .chk .fail (message_registry .SUPER_ARG_2_NOT_INSTANCE_OF_ARG_1 , e )
30033007 elif isinstance (instance_type , TypeType ) or (isinstance (instance_type , FunctionLike )
@@ -3287,7 +3291,9 @@ def has_member(self, typ: Type, member: str) -> bool:
32873291 # these two should be carefully kept in sync.
32883292 if isinstance (typ , TypeVarType ):
32893293 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 ):
32913297 typ = typ .fallback
32923298 if isinstance (typ , Instance ):
32933299 return typ .type .has_readable_member (member )
@@ -3305,7 +3311,7 @@ def has_member(self, typ: Type, member: str) -> bool:
33053311 if isinstance (item , TypeVarType ):
33063312 item = item .upper_bound
33073313 if isinstance (item , TupleType ):
3308- item = item . fallback
3314+ item = tuple_fallback ( item )
33093315 if isinstance (item , Instance ) and item .type .metaclass_type is not None :
33103316 return self .has_member (item .type .metaclass_type , member )
33113317 if isinstance (item , AnyType ):
@@ -3645,7 +3651,7 @@ def is_typetype_like(typ: Type) -> bool:
36453651 if isinstance (actual , Overloaded ):
36463652 actual = actual .items ()[0 ].fallback
36473653 if isinstance (actual , TupleType ):
3648- actual = actual . fallback
3654+ actual = tuple_fallback ( actual )
36493655 if isinstance (actual , Instance ) and formal .type in actual .type .mro :
36503656 # Try performing a quick check as an optimization
36513657 return True
0 commit comments