this repo has no description
at trunk 86 lines 2.2 kB view raw
1# Portions copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2# pyre-unsafe 3"""Parser for future statements 4 5""" 6from __future__ import print_function 7 8import ast 9 10from .visitor import ASTVisitor, walk 11 12 13def is_future(stmt): 14 """Return true if statement is a well-formed future statement""" 15 if not isinstance(stmt, ast.ImportFrom): 16 return 0 17 if stmt.module == "__future__": 18 return 1 19 else: 20 return 0 21 22 23class FutureParser(ASTVisitor): 24 25 features = ( 26 "nested_scopes", 27 "generators", 28 "division", 29 "absolute_import", 30 "with_statement", 31 "print_function", 32 "unicode_literals", 33 "generator_stop", 34 "barry_as_FLUFL", 35 "annotations", 36 ) 37 38 def __init__(self): 39 super().__init__() 40 self.found = {} # set 41 42 def visitModule(self, node): 43 for s in node.body: 44 if isinstance(s, ast.Expr) and isinstance(s.value, ast.Str): 45 continue 46 if not self.check_stmt(s): 47 break 48 49 def check_stmt(self, stmt): 50 if is_future(stmt): 51 for alias in stmt.names: 52 name = alias.name 53 if name in self.features: 54 self.found[name] = 1 55 elif name == "braces": 56 raise SyntaxError("not a chance") 57 else: 58 raise SyntaxError("future feature %s is not defined" % name) 59 stmt.valid_future = 1 60 return 1 61 return 0 62 63 def get_features(self): 64 """Return list of features enabled by future statements""" 65 return self.found.keys() 66 67 68class BadFutureParser(ASTVisitor): 69 """Check for invalid future statements""" 70 71 def visitImportFrom(self, node): 72 if hasattr(node, "valid_future"): 73 return 74 if node.module != "__future__": 75 return 76 raise SyntaxError( 77 "from __future__ imports must occur at the beginning of the file" 78 ) 79 80 81def find_futures(node): 82 p1 = FutureParser() 83 p2 = BadFutureParser() 84 walk(node, p1) 85 walk(node, p2) 86 return p1.get_features()