1from __future__ import unicode_literals 2import sys 3import ast 4import six 5 6 7class Printer(ast.NodeVisitor): 8 9 def __init__(self, file=sys.stdout, indent=" "): 10 self.indentation = 0 11 self.indent_with = indent 12 self.f = file 13 14 # overridden to make the API obvious 15 def visit(self, node): 16 super(Printer, self).visit(node) 17 18 def write(self, text): 19 self.f.write(six.text_type(text)) 20 21 def generic_visit(self, node): 22 23 if isinstance(node, list): 24 nodestart = "[" 25 nodeend = "]" 26 children = [("", child) for child in node] 27 else: 28 nodestart = type(node).__name__ + "(" 29 nodeend = ")" 30 children = [(name + "=", value) for name, value in ast.iter_fields(node)] 31 32 if len(children) > 1: 33 self.indentation += 1 34 35 self.write(nodestart) 36 for i, pair in enumerate(children): 37 attr, child = pair 38 if len(children) > 1: 39 self.write("\n" + self.indent_with * self.indentation) 40 if isinstance(child, (ast.AST, list)): 41 self.write(attr) 42 self.visit(child) 43 else: 44 self.write(attr + repr(child)) 45 46 if i != len(children) - 1: 47 self.write(",") 48 self.write(nodeend) 49 50 if len(children) > 1: 51 self.indentation -= 1 52