1 """Check for errs in the AST. 2 3 The Python parser does not catch all syntax errors. Others, like 4 assignments with invalid targets, are caught in the code generation 5 phase. 6 7 The compiler package catches some errors in the transformer module. 8 But it seems clearer to write checkers that use the AST to detect 9 errors. 10 """ 11 12 from compiler import ast, walk 13 14 def check(tree, multi=None): 15 v = SyntaxErrorChecker(multi) 16 walk(tree, v) 17 return v.errors 18 19 class SyntaxErrorChecker: 20 """A visitor to find syntax errors in the AST.""" 21 22 def __init__(self, multi=None): 23 """Create new visitor object. 24 25 If optional argument multi is not None, then print messages 26 for each error rather than raising a SyntaxError for the 27 first. 28 """ 29 self.multi = multi 30 self.errors = 0 31 32 def error(self, node, msg): 33 self.errors = self.errors + 1 34 if self.multi is not None: 35 print "%s:%s: %s" % (node.filename, node.lineno, msg) 36 else: 37 raise SyntaxError, "%s (%s:%s)" % (msg, node.filename, node.lineno) 38 39 def visitAssign(self, node): 40 # the transformer module handles many of these 41 pass 42 ## for target in node.nodes: 43 ## if isinstance(target, ast.AssList): 44 ## if target.lineno is None: 45 ## target.lineno = node.lineno 46 ## self.error(target, "can't assign to list comprehension")