3939from mypy .options import Options
4040
4141try :
42- from typed_ast import ast3
43- from typed_ast .ast3 import (
44- AST ,
45- Call ,
46- FunctionType ,
47- Name ,
48- Attribute ,
49- Ellipsis as ast3_Ellipsis ,
50- Starred ,
51- NameConstant ,
52- Expression as ast3_Expression ,
53- Str ,
54- Bytes ,
55- Index ,
56- Num ,
57- UnaryOp ,
58- USub ,
59- )
42+ # Check if we can use the stdlib ast module instead of typed_ast.
43+ if sys .version_info >= (3 , 8 ):
44+ import ast as ast3
45+ assert 'kind' in ast3 .Constant ._fields , \
46+ "This 3.8.0 alpha (%s) is too old; 3.8.0a3 required" % sys .version .split ()[0 ]
47+ from ast import (
48+ AST ,
49+ Call ,
50+ FunctionType ,
51+ Name ,
52+ Attribute ,
53+ Ellipsis as ast3_Ellipsis ,
54+ Starred ,
55+ NameConstant ,
56+ Expression as ast3_Expression ,
57+ Str ,
58+ Bytes ,
59+ Index ,
60+ Num ,
61+ UnaryOp ,
62+ USub ,
63+ )
64+
65+ def ast3_parse (source : Union [str , bytes ], filename : str , mode : str ,
66+ feature_version : int = sys .version_info [1 ]) -> AST :
67+ return ast3 .parse (source , filename , mode ,
68+ type_comments = True , # This works the magic
69+ feature_version = feature_version )
70+
71+ NamedExpr = ast3 .NamedExpr
72+ Constant = ast3 .Constant
73+ else :
74+ from typed_ast import ast3
75+ from typed_ast .ast3 import (
76+ AST ,
77+ Call ,
78+ FunctionType ,
79+ Name ,
80+ Attribute ,
81+ Ellipsis as ast3_Ellipsis ,
82+ Starred ,
83+ NameConstant ,
84+ Expression as ast3_Expression ,
85+ Str ,
86+ Bytes ,
87+ Index ,
88+ Num ,
89+ UnaryOp ,
90+ USub ,
91+ )
92+
93+ def ast3_parse (source : Union [str , bytes ], filename : str , mode : str ,
94+ feature_version : int = sys .version_info [1 ]) -> AST :
95+ return ast3 .parse (source , filename , mode , feature_version = feature_version )
96+
97+ # These don't exist before 3.8
98+ NamedExpr = Any
99+ Constant = Any
60100except ImportError :
61101 if sys .version_info .minor > 2 :
62102 try :
@@ -122,7 +162,7 @@ def parse(source: Union[str, bytes],
122162 else :
123163 assert options .python_version [0 ] >= 3
124164 feature_version = options .python_version [1 ]
125- ast = ast3 . parse (source , fnam , 'exec' , feature_version = feature_version )
165+ ast = ast3_parse (source , fnam , 'exec' , feature_version = feature_version )
126166
127167 tree = ASTConverter (options = options ,
128168 is_stub = is_stub_file ,
@@ -146,7 +186,7 @@ def parse_type_comment(type_comment: str,
146186 assume_str_is_unicode : bool = True ,
147187 ) -> Optional [Type ]:
148188 try :
149- typ = ast3 . parse (type_comment , '<type_comment>' , 'eval' )
189+ typ = ast3_parse (type_comment , '<type_comment>' , 'eval' )
150190 except SyntaxError as e :
151191 if errors is not None :
152192 errors .report (line , e .offset , TYPE_COMMENT_SYNTAX_ERROR , blocker = True )
@@ -366,16 +406,12 @@ def visit_Module(self, mod: ast3.Module) -> MypyFile:
366406 # arguments = (arg* args, arg? vararg, arg* kwonlyargs, expr* kw_defaults,
367407 # arg? kwarg, expr* defaults)
368408 def visit_FunctionDef (self , n : ast3 .FunctionDef ) -> Union [FuncDef , Decorator ]:
369- f = self .do_func_def (n )
370- f .set_line (n .lineno , n .col_offset ) # Overrides set_line -- can't use self.set_line
371- return f
409+ return self .do_func_def (n )
372410
373411 # AsyncFunctionDef(identifier name, arguments args,
374412 # stmt* body, expr* decorator_list, expr? returns, string? type_comment)
375413 def visit_AsyncFunctionDef (self , n : ast3 .AsyncFunctionDef ) -> Union [FuncDef , Decorator ]:
376- f = self .do_func_def (n , is_coroutine = True )
377- f .set_line (n .lineno , n .col_offset ) # Overrides set_line -- can't use self.set_line
378- return f
414+ return self .do_func_def (n , is_coroutine = True )
379415
380416 def do_func_def (self , n : Union [ast3 .FunctionDef , ast3 .AsyncFunctionDef ],
381417 is_coroutine : bool = False ) -> Union [FuncDef , Decorator ]:
@@ -397,7 +433,7 @@ def do_func_def(self, n: Union[ast3.FunctionDef, ast3.AsyncFunctionDef],
397433 return_type = None
398434 elif n .type_comment is not None :
399435 try :
400- func_type_ast = ast3 . parse (n .type_comment , '<func_type>' , 'func_type' )
436+ func_type_ast = ast3_parse (n .type_comment , '<func_type>' , 'func_type' )
401437 assert isinstance (func_type_ast , FunctionType )
402438 # for ellipsis arg
403439 if (len (func_type_ast .argtypes ) == 1 and
@@ -470,15 +506,25 @@ def do_func_def(self, n: Union[ast3.FunctionDef, ast3.AsyncFunctionDef],
470506 func_type .line = lineno
471507
472508 if n .decorator_list :
509+ if sys .version_info < (3 , 8 ):
510+ # Before 3.8, [typed_]ast the line number points to the first decorator.
511+ # In 3.8, it points to the 'def' line, where we want it.
512+ lineno += len (n .decorator_list )
513+
473514 var = Var (func_def .name ())
474515 var .is_ready = False
475- var .set_line (n . decorator_list [ 0 ]. lineno )
516+ var .set_line (lineno )
476517
477518 func_def .is_decorated = True
478- func_def .set_line (lineno + len (n .decorator_list ))
479- func_def .body .set_line (func_def .get_line ())
480- return Decorator (func_def , self .translate_expr_list (n .decorator_list ), var )
519+ func_def .set_line (lineno , n .col_offset )
520+ func_def .body .set_line (lineno ) # TODO: Why?
521+
522+ deco = Decorator (func_def , self .translate_expr_list (n .decorator_list ), var )
523+ deco .set_line (n .decorator_list [0 ].lineno )
524+ return deco
481525 else :
526+ # FuncDef overrides set_line -- can't use self.set_line
527+ func_def .set_line (lineno , n .col_offset )
482528 return func_def
483529
484530 def set_type_optional (self , type : Optional [Type ], initializer : Optional [Expression ]) -> None :
@@ -568,7 +614,15 @@ def visit_ClassDef(self, n: ast3.ClassDef) -> ClassDef:
568614 metaclass = dict (keywords ).get ('metaclass' ),
569615 keywords = keywords )
570616 cdef .decorators = self .translate_expr_list (n .decorator_list )
571- self .set_line (cdef , n )
617+ if n .decorator_list and sys .version_info >= (3 , 8 ):
618+ # Before 3.8, n.lineno points to the first decorator; in
619+ # 3.8, it points to the 'class' statement. We always make
620+ # it point to the first decorator. (The node structure
621+ # here is different than for decorated functions.)
622+ cdef .line = n .decorator_list [0 ].lineno
623+ cdef .column = n .col_offset
624+ else :
625+ self .set_line (cdef , n )
572626 self .class_nesting -= 1
573627 return cdef
574628
@@ -617,6 +671,10 @@ def visit_AugAssign(self, n: ast3.AugAssign) -> OperatorAssignmentStmt:
617671 self .visit (n .value ))
618672 return self .set_line (s , n )
619673
674+ def visit_NamedExpr (self , n : NamedExpr ) -> None :
675+ self .fail ("assignment expressions are not yet supported" , n .lineno , n .col_offset )
676+ return None
677+
620678 # For(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)
621679 def visit_For (self , n : ast3 .For ) -> ForStmt :
622680 if n .type_comment is not None :
@@ -926,6 +984,30 @@ def visit_Call(self, n: Call) -> CallExpr:
926984 cast ('List[Optional[str]]' , [None ] * len (args )) + keyword_names )
927985 return self .set_line (e , n )
928986
987+ # Constant(object value) -- a constant, in Python 3.8.
988+ def visit_Constant (self , n : Constant ) -> Any :
989+ val = n .value
990+ e = None # type: Any
991+ if val is None :
992+ e = NameExpr ('None' )
993+ elif isinstance (val , str ):
994+ e = StrExpr (n .s )
995+ elif isinstance (val , bytes ):
996+ e = BytesExpr (bytes_to_human_readable_repr (n .s ))
997+ elif isinstance (val , bool ): # Must check before int!
998+ e = NameExpr (str (val ))
999+ elif isinstance (val , int ):
1000+ e = IntExpr (val )
1001+ elif isinstance (val , float ):
1002+ e = FloatExpr (val )
1003+ elif isinstance (val , complex ):
1004+ e = ComplexExpr (val )
1005+ elif val is Ellipsis :
1006+ e = EllipsisExpr ()
1007+ else :
1008+ raise RuntimeError ('Constant not implemented for ' + str (type (val )))
1009+ return self .set_line (e , n )
1010+
9291011 # Num(object n) -- a number as a PyObject.
9301012 def visit_Num (self , n : ast3 .Num ) -> Union [IntExpr , FloatExpr , ComplexExpr ]:
9311013 # The n field has the type complex, but complex isn't *really*
@@ -994,7 +1076,8 @@ def visit_Bytes(self, n: ast3.Bytes) -> Union[BytesExpr, StrExpr]:
9941076
9951077 # NameConstant(singleton value)
9961078 def visit_NameConstant (self , n : NameConstant ) -> NameExpr :
997- return NameExpr (str (n .value ))
1079+ e = NameExpr (str (n .value ))
1080+ return self .set_line (e , n )
9981081
9991082 # Ellipsis
10001083 def visit_Ellipsis (self , n : ast3_Ellipsis ) -> EllipsisExpr :
@@ -1094,7 +1177,7 @@ def invalid_type(self, node: AST, note: Optional[str] = None) -> RawExpressionTy
10941177 def visit (self , node : ast3 .expr ) -> Type : ...
10951178
10961179 @overload # noqa
1097- def visit (self , node : Optional [AST ]) -> Optional [Type ]: ...
1180+ def visit (self , node : Optional [AST ]) -> Optional [Type ]: ... # noqa
10981181
10991182 def visit (self , node : Optional [AST ]) -> Optional [Type ]: # noqa
11001183 """Modified visit -- keep track of the stack of nodes"""
@@ -1205,6 +1288,34 @@ def visit_NameConstant(self, n: NameConstant) -> Type:
12051288 else :
12061289 return UnboundType (str (n .value ), line = self .line )
12071290
1291+ # Only for 3.8 and newer
1292+ def visit_Constant (self , n : Constant ) -> Type :
1293+ val = n .value
1294+ if val is None :
1295+ # None is a type.
1296+ return UnboundType ('None' , line = self .line )
1297+ if isinstance (val , str ):
1298+ # Parse forward reference.
1299+ if (n .kind and 'u' in n .kind ) or self .assume_str_is_unicode :
1300+ return parse_type_string (n .s , 'builtins.unicode' , self .line , n .col_offset ,
1301+ assume_str_is_unicode = self .assume_str_is_unicode )
1302+ else :
1303+ return parse_type_string (n .s , 'builtins.str' , self .line , n .col_offset ,
1304+ assume_str_is_unicode = self .assume_str_is_unicode )
1305+ if val is Ellipsis :
1306+ # '...' is valid in some types.
1307+ return EllipsisType (line = self .line )
1308+ if isinstance (val , bool ):
1309+ # Special case for True/False.
1310+ return RawExpressionType (val , 'builtins.bool' , line = self .line )
1311+ if isinstance (val , (int , float , complex )):
1312+ return self .numeric_type (val , n )
1313+ if isinstance (val , bytes ):
1314+ contents = bytes_to_human_readable_repr (val )
1315+ return RawExpressionType (contents , 'builtins.bytes' , self .line , column = n .col_offset )
1316+ # Everything else is invalid.
1317+ return self .invalid_type (n )
1318+
12081319 # UnaryOp(op, operand)
12091320 def visit_UnaryOp (self , n : UnaryOp ) -> Type :
12101321 # We support specifically Literal[-4] and nothing else.
@@ -1216,13 +1327,11 @@ def visit_UnaryOp(self, n: UnaryOp) -> Type:
12161327 return typ
12171328 return self .invalid_type (n )
12181329
1219- # Num(number n)
1220- def visit_Num (self , n : Num ) -> Type :
1221- # The n field has the type complex, but complex isn't *really*
1330+ def numeric_type (self , value : object , n : AST ) -> Type :
1331+ # The node's field has the type complex, but complex isn't *really*
12221332 # a parent of int and float, and this causes isinstance below
12231333 # to think that the complex branch is always picked. Avoid
12241334 # this by throwing away the type.
1225- value = n .n # type: object
12261335 if isinstance (value , int ):
12271336 numeric_value = value # type: Optional[int]
12281337 type_name = 'builtins.int'
@@ -1239,24 +1348,31 @@ def visit_Num(self, n: Num) -> Type:
12391348 column = getattr (n , 'col_offset' , - 1 ),
12401349 )
12411350
1242- # Str(string s)
1243- def visit_Str (self , n : Str ) -> Type :
1244- # Note: we transform these fallback types into the correct types in
1245- # 'typeanal.py' -- specifically in the named_type_with_normalized_str method.
1246- # If we're analyzing Python 3, that function will translate 'builtins.unicode'
1247- # into 'builtins.str'. In contrast, if we're analyzing Python 2 code, we'll
1248- # translate 'builtins.bytes' in the method below into 'builtins.str'.
1249- if 'u' in n .kind or self .assume_str_is_unicode :
1250- return parse_type_string (n .s , 'builtins.unicode' , self .line , n .col_offset ,
1251- assume_str_is_unicode = self .assume_str_is_unicode )
1252- else :
1253- return parse_type_string (n .s , 'builtins.str' , self .line , n .col_offset ,
1254- assume_str_is_unicode = self .assume_str_is_unicode )
1351+ if sys .version_info < (3 , 8 ):
1352+ # Using typed_ast
1353+
1354+ # Num(number n)
1355+ def visit_Num (self , n : Num ) -> Type :
1356+ return self .numeric_type (n .n , n )
1357+
1358+ # Str(string s)
1359+ def visit_Str (self , n : Str ) -> Type :
1360+ # Note: we transform these fallback types into the correct types in
1361+ # 'typeanal.py' -- specifically in the named_type_with_normalized_str method.
1362+ # If we're analyzing Python 3, that function will translate 'builtins.unicode'
1363+ # into 'builtins.str'. In contrast, if we're analyzing Python 2 code, we'll
1364+ # translate 'builtins.bytes' in the method below into 'builtins.str'.
1365+ if 'u' in n .kind or self .assume_str_is_unicode :
1366+ return parse_type_string (n .s , 'builtins.unicode' , self .line , n .col_offset ,
1367+ assume_str_is_unicode = self .assume_str_is_unicode )
1368+ else :
1369+ return parse_type_string (n .s , 'builtins.str' , self .line , n .col_offset ,
1370+ assume_str_is_unicode = self .assume_str_is_unicode )
12551371
1256- # Bytes(bytes s)
1257- def visit_Bytes (self , n : Bytes ) -> Type :
1258- contents = bytes_to_human_readable_repr (n .s )
1259- return RawExpressionType (contents , 'builtins.bytes' , self .line , column = n .col_offset )
1372+ # Bytes(bytes s)
1373+ def visit_Bytes (self , n : Bytes ) -> Type :
1374+ contents = bytes_to_human_readable_repr (n .s )
1375+ return RawExpressionType (contents , 'builtins.bytes' , self .line , column = n .col_offset )
12601376
12611377 # Subscript(expr value, slice slice, expr_context ctx)
12621378 def visit_Subscript (self , n : ast3 .Subscript ) -> Type :
0 commit comments