from __future__ import unicode_literals import sys import ast import six class Printer(ast.NodeVisitor): def __init__(self, file=sys.stdout, indent=" "): self.indentation = 0 self.indent_with = indent self.f = file # overridden to make the API obvious def visit(self, node): super(Printer, self).visit(node) def write(self, text): self.f.write(six.text_type(text)) def generic_visit(self, node): if isinstance(node, list): nodestart = "[" nodeend = "]" children = [("", child) for child in node] else: nodestart = type(node).__name__ + "(" nodeend = ")" children = [(name + "=", value) for name, value in ast.iter_fields(node)] if len(children) > 1: self.indentation += 1 self.write(nodestart) for i, pair in enumerate(children): attr, child = pair if len(children) > 1: self.write("\n" + self.indent_with * self.indentation) if isinstance(child, (ast.AST, list)): self.write(attr) self.visit(child) else: self.write(attr + repr(child)) if i != len(children) - 1: self.write(",") self.write(nodeend) if len(children) > 1: self.indentation -= 1