blob: a39dd13dadd9b3945129b159d1ac7cb0d1236a5a [file] [log] [blame]
Guido van Rossum5e92aff1997-04-16 00:49:59 +00001# pprint.py
2#
3# Author: Fred L. Drake, Jr.
4# fdrake@cnri.reston.va.us, fdrake@intr.net
5#
6# This is a simple little module I wrote to make life easier. I didn't
7# see anything quite like it in the library, though I may have overlooked
8# something. I wrote this when I was trying to read some heavily nested
9# tuples with fairly non-descriptive content. This is modelled very much
10# after Lisp/Scheme - style pretty-printing of lists. If you find it
11# useful, thank small children who sleep at night.
12
13"""Support to pretty-print lists, tuples, & dictionaries recursively.
14
15Very simple, but useful, especially in debugging data structures.
16
17Functions
18---------
19
20pformat()
21 Format a Python object into a pretty-printed representation.
22
23pprint()
24 Pretty-print a list, tuple or dictionary.
25
26
27
28Constants
29---------
30
31INDENT_PER_LEVEL
32 Amount of indentation to use for each new recursive level. The
33 default is 1. This must be a non-negative integer, and may be set
34 by the caller before calling pprint().
35
36MAX_WIDTH
37 Maximum width of the display. This is only used if the
38 representation *can* be kept less than MAX_WIDTH characters wide.
39 May be set by the user before calling pprint() if needed.
40
41"""
42
43INDENT_PER_LEVEL = 1
44
45MAX_WIDTH = 80
46
47from types import DictType, ListType, TupleType
48
49
50def pformat(seq):
51 """Format a Python object into a pretty-printed representation.
52
53 The representation is returned with no trailing newline.
54
55 """
56 import StringIO
57 sio = StringIO.StringIO()
58 pprint(seq, stream=sio)
59 str = sio.getvalue()
60 if str and str[-1] == '\n':
61 str = str[:-1]
62 return str
63
64
65def pprint(seq, stream=None, indent=0, allowance=0):
66 """Pretty-print a list, tuple, or dictionary.
67
68 seq
69 List, tuple, or dictionary object to be pretty-printed. Other
70 object types are permitted by are not specially interpreted.
71
72 stream
73 Output stream. If not provided, `sys.stdout' is used. This
74 parameter must support the `write()' method with a single
75 parameter, which will always be a string. It may be a
76 `StringIO.StringIO' object if the result is needed as a
77 string.
78
79 Indentation is done according to `INDENT_PER_LEVEL', which may be
80 set to any non-negative integer before calling this function. The
81 output written on the stream is a perfectly valid representation
82 of the Python object passed in, with indentation to assist
83 human-readable interpretation. The output can be used as input
84 without error, given readable representations of all elements are
85 available via `repr()'. Output is restricted to `MAX_WIDTH'
86 columns where possible.
87
88 """
89 if stream is None:
90 import sys
91 stream = sys.stdout
92
93 rep = `seq`
94 typ = type(seq)
95 sepLines = len(rep) > (MAX_WIDTH - 1 - indent - allowance)
96
97 if sepLines and (typ is ListType or typ is TupleType):
98 # Pretty-print the sequence.
99 stream.write(((typ is ListType) and '[') or '(')
100
101 length = len(seq)
102 if length:
103 indent = indent + INDENT_PER_LEVEL
104 pprint(seq[0], stream, indent, allowance + 1)
105
106 if len(seq) > 1:
107 for ent in seq[1:]:
108 stream.write(',\n' + ' '*indent)
109 pprint(ent, stream, indent, allowance + 1)
110
111 indent = indent - INDENT_PER_LEVEL
112
113 stream.write(((typ is ListType) and ']') or ')')
114
115 elif typ is DictType and sepLines:
116 stream.write('{')
117
118 length = len(seq)
119 if length:
120 indent = indent + INDENT_PER_LEVEL
121 items = seq.items()
122 items.sort()
123 key, ent = items[0]
124 rep = `key` + ': '
125 stream.write(rep)
126 pprint(ent, stream, indent + len(rep), allowance + 1)
127
128 if len(items) > 1:
129 for key, ent in items[1:]:
130 rep = `key` + ': '
131 stream.write(',\n' + ' '*indent + rep)
132 pprint(ent, stream, indent + len(rep), allowance + 1)
133
134 indent = indent - INDENT_PER_LEVEL
135
136 stream.write('}')
137
138 else:
139 stream.write(rep)
140
141 # Terminate the 'print' if we're not a recursive invocation.
142 if not indent:
143 stream.write('\n')