11"""Semantic analysis of types"""
22
33from collections import OrderedDict
4- from typing import Callable , cast , List , Optional
4+ from typing import Callable , List , Optional , Set
55
66from mypy .types import (
7- Type , UnboundType , TypeVarType , TupleType , TypedDictType , UnionType , Instance ,
7+ Type , UnboundType , TypeVarType , TupleType , TypedDictType , UnionType , Instance , TypeVarId ,
88 AnyType , CallableType , Void , NoneTyp , DeletedType , TypeList , TypeVarDef , TypeVisitor ,
99 StarType , PartialType , EllipsisType , UninhabitedType , TypeType , get_typ_args , set_typ_args ,
10+ get_type_vars ,
1011)
1112from mypy .nodes import (
1213 BOUND_TVAR , UNBOUND_TVAR , TYPE_ALIAS , UNBOUND_IMPORTED ,
@@ -81,11 +82,15 @@ def __init__(self,
8182 lookup_func : Callable [[str , Context ], SymbolTableNode ],
8283 lookup_fqn_func : Callable [[str ], SymbolTableNode ],
8384 fail_func : Callable [[str , Context ], None ], * ,
84- aliasing : bool = False ) -> None :
85+ aliasing : bool = False ,
86+ allow_tuple_literal : bool = False ) -> None :
8587 self .lookup = lookup_func
8688 self .lookup_fqn_func = lookup_fqn_func
8789 self .fail = fail_func
8890 self .aliasing = aliasing
91+ self .allow_tuple_literal = allow_tuple_literal
92+ # Positive if we are analyzing arguments of another (outer) type
93+ self .nesting_level = 0
8994
9095 def visit_unbound_type (self , t : UnboundType ) -> Type :
9196 if t .optional :
@@ -120,7 +125,7 @@ def visit_unbound_type(self, t: UnboundType) -> Type:
120125 return self .builtin_type ('builtins.tuple' )
121126 if len (t .args ) == 2 and isinstance (t .args [1 ], EllipsisType ):
122127 # Tuple[T, ...] (uniform, variable-length tuple)
123- instance = self .builtin_type ('builtins.tuple' , [t .args [0 ]. accept ( self )])
128+ instance = self .builtin_type ('builtins.tuple' , [self . anal_type ( t .args [0 ])])
124129 instance .line = t .line
125130 return instance
126131 return self .tuple_type (self .anal_array (t .args ))
@@ -132,22 +137,34 @@ def visit_unbound_type(self, t: UnboundType) -> Type:
132137 if len (t .args ) != 1 :
133138 self .fail ('Optional[...] must have exactly one type argument' , t )
134139 return AnyType ()
135- items = self .anal_array (t .args )
140+ item = self .anal_type (t .args [ 0 ] )
136141 if experiments .STRICT_OPTIONAL :
137- return UnionType .make_simplified_union ([items [ 0 ] , NoneTyp ()])
142+ return UnionType .make_simplified_union ([item , NoneTyp ()])
138143 else :
139144 # Without strict Optional checking Optional[t] is just an alias for t.
140- return items [ 0 ]
145+ return item
141146 elif fullname == 'typing.Callable' :
142147 return self .analyze_callable_type (t )
143148 elif fullname == 'typing.Type' :
144149 if len (t .args ) == 0 :
145150 return TypeType (AnyType (), line = t .line )
146151 if len (t .args ) != 1 :
147152 self .fail ('Type[...] must have exactly one type argument' , t )
148- items = self .anal_array (t .args )
149- item = items [0 ]
153+ item = self .anal_type (t .args [0 ])
150154 return TypeType (item , line = t .line )
155+ elif fullname == 'typing.ClassVar' :
156+ if self .nesting_level > 0 :
157+ self .fail ('Invalid type: ClassVar nested inside other type' , t )
158+ if len (t .args ) == 0 :
159+ return AnyType (line = t .line )
160+ if len (t .args ) != 1 :
161+ self .fail ('ClassVar[...] must have at most one type argument' , t )
162+ return AnyType ()
163+ item = self .anal_type (t .args [0 ])
164+ if isinstance (item , TypeVarType ) or get_type_vars (item ):
165+ self .fail ('Invalid type: ClassVar cannot be generic' , t )
166+ return AnyType ()
167+ return item
151168 elif fullname == 'mypy_extensions.NoReturn' :
152169 return UninhabitedType (is_noreturn = True )
153170 elif sym .kind == TYPE_ALIAS :
@@ -290,31 +307,38 @@ def visit_type_var(self, t: TypeVarType) -> Type:
290307 return t
291308
292309 def visit_callable_type (self , t : CallableType ) -> Type :
293- return t .copy_modified (arg_types = self .anal_array (t .arg_types ),
294- ret_type = t .ret_type . accept ( self ),
310+ return t .copy_modified (arg_types = self .anal_array (t .arg_types , nested = False ),
311+ ret_type = self . anal_type ( t .ret_type , nested = False ),
295312 fallback = t .fallback or self .builtin_type ('builtins.function' ),
296313 variables = self .anal_var_defs (t .variables ))
297314
298315 def visit_tuple_type (self , t : TupleType ) -> Type :
299- if t .implicit :
316+ # Types such as (t1, t2, ...) only allowed in assignment statements. They'll
317+ # generate errors elsewhere, and Tuple[t1, t2, ...] must be used instead.
318+ if t .implicit and not self .allow_tuple_literal :
300319 self .fail ('Invalid tuple literal type' , t )
301320 return AnyType ()
302321 star_count = sum (1 for item in t .items if isinstance (item , StarType ))
303322 if star_count > 1 :
304323 self .fail ('At most one star type allowed in a tuple' , t )
305- return AnyType ()
324+ if t .implicit :
325+ return TupleType ([AnyType () for _ in t .items ],
326+ self .builtin_type ('builtins.tuple' ),
327+ t .line )
328+ else :
329+ return AnyType ()
306330 fallback = t .fallback if t .fallback else self .builtin_type ('builtins.tuple' , [AnyType ()])
307331 return TupleType (self .anal_array (t .items ), fallback , t .line )
308332
309333 def visit_typeddict_type (self , t : TypedDictType ) -> Type :
310334 items = OrderedDict ([
311- (item_name , item_type . accept ( self ))
335+ (item_name , self . anal_type ( item_type ))
312336 for (item_name , item_type ) in t .items .items ()
313337 ])
314338 return TypedDictType (items , t .fallback )
315339
316340 def visit_star_type (self , t : StarType ) -> Type :
317- return StarType (t .type . accept ( self ), t .line )
341+ return StarType (self . anal_type ( t .type ), t .line )
318342
319343 def visit_union_type (self , t : UnionType ) -> Type :
320344 return UnionType (self .anal_array (t .items ), t .line )
@@ -327,7 +351,7 @@ def visit_ellipsis_type(self, t: EllipsisType) -> Type:
327351 return AnyType ()
328352
329353 def visit_type_type (self , t : TypeType ) -> Type :
330- return TypeType (t .item . accept ( self ), line = t .line )
354+ return TypeType (self . anal_type ( t .item ), line = t .line )
331355
332356 def analyze_callable_type (self , t : UnboundType ) -> Type :
333357 fallback = self .builtin_type ('builtins.function' )
@@ -340,7 +364,7 @@ def analyze_callable_type(self, t: UnboundType) -> Type:
340364 fallback = fallback ,
341365 is_ellipsis_args = True )
342366 elif len (t .args ) == 2 :
343- ret_type = t .args [1 ]. accept ( self )
367+ ret_type = self . anal_type ( t .args [1 ])
344368 if isinstance (t .args [0 ], TypeList ):
345369 # Callable[[ARG, ...], RET] (ordinary callable type)
346370 args = t .args [0 ].items
@@ -364,12 +388,21 @@ def analyze_callable_type(self, t: UnboundType) -> Type:
364388 self .fail ('Invalid function type' , t )
365389 return AnyType ()
366390
367- def anal_array (self , a : List [Type ]) -> List [Type ]:
391+ def anal_array (self , a : List [Type ], nested : bool = True ) -> List [Type ]:
368392 res = [] # type: List[Type]
369393 for t in a :
370- res .append (t . accept ( self ))
394+ res .append (self . anal_type ( t , nested ))
371395 return res
372396
397+ def anal_type (self , t : Type , nested : bool = True ) -> Type :
398+ if nested :
399+ self .nesting_level += 1
400+ try :
401+ return t .accept (self )
402+ finally :
403+ if nested :
404+ self .nesting_level -= 1
405+
373406 def anal_var_defs (self , var_defs : List [TypeVarDef ]) -> List [TypeVarDef ]:
374407 a = [] # type: List[TypeVarDef]
375408 for vd in var_defs :
0 commit comments