Fix a bug in the ``compiler`` package that caused invalid code to be
[python/dscho.git] / Lib / compiler / future.py
blobfef189e9e91dedbb27b39f7b9a66a5a020c1c339
1 """Parser for future statements
3 """
5 from compiler import ast, walk
7 def is_future(stmt):
8 """Return true if statement is a well-formed future statement"""
9 if not isinstance(stmt, ast.From):
10 return 0
11 if stmt.modname == "__future__":
12 return 1
13 else:
14 return 0
16 class FutureParser:
18 features = ("nested_scopes", "generators", "division",
19 "absolute_import", "with_statement")
21 def __init__(self):
22 self.found = {} # set
24 def visitModule(self, node):
25 stmt = node.node
26 for s in stmt.nodes:
27 if not self.check_stmt(s):
28 break
30 def check_stmt(self, stmt):
31 if is_future(stmt):
32 for name, asname in stmt.names:
33 if name in self.features:
34 self.found[name] = 1
35 else:
36 raise SyntaxError, \
37 "future feature %s is not defined" % name
38 stmt.valid_future = 1
39 return 1
40 return 0
42 def get_features(self):
43 """Return list of features enabled by future statements"""
44 return self.found.keys()
46 class BadFutureParser:
47 """Check for invalid future statements"""
49 def visitFrom(self, node):
50 if hasattr(node, 'valid_future'):
51 return
52 if node.modname != "__future__":
53 return
54 raise SyntaxError, "invalid future statement " + repr(node)
56 def find_futures(node):
57 p1 = FutureParser()
58 p2 = BadFutureParser()
59 walk(node, p1)
60 walk(node, p2)
61 return p1.get_features()
63 if __name__ == "__main__":
64 import sys
65 from compiler import parseFile, walk
67 for file in sys.argv[1:]:
68 print file
69 tree = parseFile(file)
70 v = FutureParser()
71 walk(tree, v)
72 print v.found
73 print