6
6
7
7
from contextlib import contextmanager
8
8
9
+ from mypy .options import Options
9
10
from mypy .types import (
10
11
Type , UnboundType , TypeVarType , TupleType , TypedDictType , UnionType , Instance ,
11
12
AnyType , CallableType , NoneTyp , DeletedType , TypeList , TypeVarDef , TypeVisitor ,
15
16
)
16
17
17
18
from mypy .nodes import (
18
- TVAR , TYPE_ALIAS , UNBOUND_IMPORTED ,
19
- TypeInfo , Context , SymbolTableNode , Var , Expression ,
20
- IndexExpr , RefExpr , nongen_builtins , check_arg_names , check_arg_kinds ,
21
- ARG_POS , ARG_NAMED , ARG_OPT , ARG_NAMED_OPT , ARG_STAR , ARG_STAR2 , TypeVarExpr
19
+ TVAR , TYPE_ALIAS , UNBOUND_IMPORTED , TypeInfo , Context , SymbolTableNode , Var , Expression ,
20
+ IndexExpr , RefExpr , nongen_builtins , check_arg_names , check_arg_kinds , ARG_POS , ARG_NAMED ,
21
+ ARG_OPT , ARG_NAMED_OPT , ARG_STAR , ARG_STAR2 , TypeVarExpr
22
22
)
23
23
from mypy .tvar_scope import TypeVarScope
24
24
from mypy .sametypes import is_same_type
25
25
from mypy .exprtotype import expr_to_unanalyzed_type , TypeTranslationError
26
26
from mypy .subtypes import is_subtype
27
27
from mypy .plugin import Plugin , AnalyzerPluginInterface , AnalyzeTypeContext
28
- from mypy import nodes
29
- from mypy import experiments
28
+ from mypy import nodes , messages
30
29
31
30
32
31
T = TypeVar ('T' )
@@ -56,6 +55,8 @@ def analyze_type_alias(node: Expression,
56
55
tvar_scope : TypeVarScope ,
57
56
fail_func : Callable [[str , Context ], None ],
58
57
plugin : Plugin ,
58
+ options : Options ,
59
+ is_typeshed_stub : bool ,
59
60
allow_unnormalized : bool = False ) -> Optional [Type ]:
60
61
"""Return type if node is valid as a type alias rvalue.
61
62
@@ -98,8 +99,8 @@ def analyze_type_alias(node: Expression,
98
99
except TypeTranslationError :
99
100
fail_func ('Invalid type alias' , node )
100
101
return None
101
- analyzer = TypeAnalyser (lookup_func , lookup_fqn_func , tvar_scope , fail_func , plugin ,
102
- aliasing = True , allow_unnormalized = allow_unnormalized )
102
+ analyzer = TypeAnalyser (lookup_func , lookup_fqn_func , tvar_scope , fail_func , plugin , options ,
103
+ is_typeshed_stub , aliasing = True , allow_unnormalized = allow_unnormalized )
103
104
return type .accept (analyzer )
104
105
105
106
@@ -122,7 +123,9 @@ def __init__(self,
122
123
lookup_fqn_func : Callable [[str ], SymbolTableNode ],
123
124
tvar_scope : TypeVarScope ,
124
125
fail_func : Callable [[str , Context ], None ],
125
- plugin : Plugin , * ,
126
+ plugin : Plugin ,
127
+ options : Options ,
128
+ is_typeshed_stub : bool , * ,
126
129
aliasing : bool = False ,
127
130
allow_tuple_literal : bool = False ,
128
131
allow_unnormalized : bool = False ) -> None :
@@ -136,6 +139,8 @@ def __init__(self,
136
139
self .nesting_level = 0
137
140
self .allow_unnormalized = allow_unnormalized
138
141
self .plugin = plugin
142
+ self .options = options
143
+ self .is_typeshed_stub = is_typeshed_stub
139
144
140
145
def visit_unbound_type (self , t : UnboundType ) -> Type :
141
146
if t .optional :
@@ -170,7 +175,11 @@ def visit_unbound_type(self, t: UnboundType) -> Type:
170
175
elif fullname == 'typing.Tuple' :
171
176
if len (t .args ) == 0 and not t .empty_tuple_index :
172
177
# Bare 'Tuple' is same as 'tuple'
173
- return self .named_type ('builtins.tuple' )
178
+ if 'generics' in self .options .disallow_any and not self .is_typeshed_stub :
179
+ self .fail (messages .BARE_GENERIC , t )
180
+ typ = self .named_type ('builtins.tuple' , line = t .line , column = t .column )
181
+ typ .from_generic_builtin = True
182
+ return typ
174
183
if len (t .args ) == 2 and isinstance (t .args [1 ], EllipsisType ):
175
184
# Tuple[T, ...] (uniform, variable-length tuple)
176
185
instance = self .named_type ('builtins.tuple' , [self .anal_type (t .args [0 ])])
@@ -190,7 +199,8 @@ def visit_unbound_type(self, t: UnboundType) -> Type:
190
199
return self .analyze_callable_type (t )
191
200
elif fullname == 'typing.Type' :
192
201
if len (t .args ) == 0 :
193
- return TypeType (AnyType (), line = t .line )
202
+ any_type = AnyType (from_omitted_generics = True , line = t .line , column = t .column )
203
+ return TypeType (any_type , line = t .line , column = t .column )
194
204
if len (t .args ) != 1 :
195
205
self .fail ('Type[...] must have exactly one type argument' , t )
196
206
item = self .anal_type (t .args [0 ])
@@ -219,7 +229,8 @@ def visit_unbound_type(self, t: UnboundType) -> Type:
219
229
act_len = len (an_args )
220
230
if exp_len > 0 and act_len == 0 :
221
231
# Interpret bare Alias same as normal generic, i.e., Alias[Any, Any, ...]
222
- return self .replace_alias_tvars (override , all_vars , [AnyType ()] * exp_len ,
232
+ any_type = AnyType (from_omitted_generics = True , line = t .line , column = t .column )
233
+ return self .replace_alias_tvars (override , all_vars , [any_type ] * exp_len ,
223
234
t .line , t .column )
224
235
if exp_len == 0 and act_len == 0 :
225
236
return override
@@ -255,6 +266,7 @@ def visit_unbound_type(self, t: UnboundType) -> Type:
255
266
# valid count at this point. Thus we may construct an
256
267
# Instance with an invalid number of type arguments.
257
268
instance = Instance (info , self .anal_array (t .args ), t .line , t .column )
269
+ instance .from_generic_builtin = sym .normalized
258
270
tup = info .tuple_type
259
271
if tup is not None :
260
272
# The class has a Tuple[...] base class so it will be
@@ -395,10 +407,11 @@ def analyze_callable_type(self, t: UnboundType) -> Type:
395
407
fallback = self .named_type ('builtins.function' )
396
408
if len (t .args ) == 0 :
397
409
# Callable (bare). Treat as Callable[..., Any].
398
- ret = CallableType ([AnyType (), AnyType ()],
410
+ any_type = AnyType (from_omitted_generics = True , line = t .line , column = t .column )
411
+ ret = CallableType ([any_type , any_type ],
399
412
[nodes .ARG_STAR , nodes .ARG_STAR2 ],
400
413
[None , None ],
401
- ret_type = AnyType () ,
414
+ ret_type = any_type ,
402
415
fallback = fallback ,
403
416
is_ellipsis_args = True )
404
417
elif len (t .args ) == 2 :
@@ -552,10 +565,13 @@ def anal_var_defs(self, var_defs: List[TypeVarDef]) -> List[TypeVarDef]:
552
565
vd .line ))
553
566
return a
554
567
555
- def named_type (self , fully_qualified_name : str , args : List [Type ] = None ) -> Instance :
568
+ def named_type (self , fully_qualified_name : str ,
569
+ args : List [Type ] = None ,
570
+ line : int = - 1 ,
571
+ column : int = - 1 ) -> Instance :
556
572
node = self .lookup_fqn_func (fully_qualified_name )
557
573
assert isinstance (node .node , TypeInfo )
558
- return Instance (node .node , args or [])
574
+ return Instance (node .node , args or [], line = line , column = column )
559
575
560
576
def tuple_type (self , items : List [Type ]) -> TupleType :
561
577
return TupleType (items , fallback = self .named_type ('builtins.tuple' , [AnyType ()]))
@@ -581,16 +597,29 @@ class TypeAnalyserPass3(TypeVisitor[None]):
581
597
to types.
582
598
"""
583
599
584
- def __init__ (self , fail_func : Callable [[str , Context ], None ]) -> None :
600
+ def __init__ (self ,
601
+ fail_func : Callable [[str , Context ], None ],
602
+ options : Options ,
603
+ is_typeshed_stub : bool ) -> None :
585
604
self .fail = fail_func
605
+ self .options = options
606
+ self .is_typeshed_stub = is_typeshed_stub
586
607
587
608
def visit_instance (self , t : Instance ) -> None :
588
609
info = t .type
589
610
# Check type argument count.
590
611
if len (t .args ) != len (info .type_vars ):
591
612
if len (t .args ) == 0 :
613
+ from_builtins = t .type .fullname () in nongen_builtins and not t .from_generic_builtin
614
+ if ('generics' in self .options .disallow_any and
615
+ not self .is_typeshed_stub and
616
+ from_builtins ):
617
+ alternative = nongen_builtins [t .type .fullname ()]
618
+ self .fail (messages .GENERIC_BUILTIN_TYPES_DISALLOWED .format (alternative ), t )
592
619
# Insert implicit 'Any' type arguments.
593
- t .args = [AnyType ()] * len (info .type_vars )
620
+ any_type = AnyType (from_omitted_generics = not from_builtins , line = t .line ,
621
+ column = t .line )
622
+ t .args = [any_type ] * len (info .type_vars )
594
623
return
595
624
# Invalid number of type parameters.
596
625
n = len (info .type_vars )
@@ -775,6 +804,26 @@ def visit_typeddict_type(self, t: TypedDictType) -> bool:
775
804
return False
776
805
777
806
807
+ def collect_any_types (t : Type ) -> List [AnyType ]:
808
+ """Return all inner `AnyType`s of type t"""
809
+ return t .accept (CollectAnyTypesQuery ())
810
+
811
+
812
+ class CollectAnyTypesQuery (TypeQuery [List [AnyType ]]):
813
+ def __init__ (self ) -> None :
814
+ super ().__init__ (self .combine_lists_strategy )
815
+
816
+ def visit_any (self , t : AnyType ) -> List [AnyType ]:
817
+ return [t ]
818
+
819
+ @classmethod
820
+ def combine_lists_strategy (cls , it : Iterable [List [AnyType ]]) -> List [AnyType ]:
821
+ result = [] # type: List[AnyType]
822
+ for l in it :
823
+ result .extend (l )
824
+ return result
825
+
826
+
778
827
def make_optional_type (t : Type ) -> Type :
779
828
"""Return the type corresponding to Optional[t].
780
829
0 commit comments