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