blob: c4b815800c1de3e1933f311c7754d14065ea2cd3 [file] [log] [blame]
Guido van Rossum16d27e31996-08-21 16:28:53 +00001# pprint.py
2#
3# Author: Fred L. Drake, Jr.
4# fdrake@vt.edu
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
14"""Support to pretty-print lists, tuples, & dictionaries recursively.
15Very simple, but at least somewhat useful, especially in debugging
16data structures.
17
18INDENT_PER_LEVEL -- Amount of indentation to use for each new
19 recursive level. The default is 1. This
20 must be a non-negative integer, and may be
21 set by the caller before calling pprint().
22
23MAX_WIDTH -- Maximum width of the display. This is only
24 used if the representation *can* be kept
25 less than MAX_WIDTH characters wide. May
26 be set by the user before calling pprint().
27
28TAB_WIDTH -- The width represented by a single tab. This
29 value is typically 8, but 4 is the default
30 under MacOS. Can be changed by the user if
31 desired, but is probably not a good idea.
32
33pprint(seq [, stream]) -- The pretty-printer. This takes a Python
34 object (presumably a sequence, but that
35 doesn't matter) and an optional output
36 stream. See the function documentation
37 for details.
38"""
39
40
41INDENT_PER_LEVEL = 1
42
43MAX_WIDTH = 80
44
45import os
46TAB_WIDTH = (os.name == 'mac' and 4) or 8
47del os
48
49
50
51def _indentation(cols):
52 "Create tabbed indentation string COLS columns wide."
53
54 # This is used to reduce the byte-count for the output, allowing
55 # files created using this module to use as little external storage
56 # as possible. This is primarily intended to minimize impact on
57 # a user's quota when storing resource files, or for creating output
58 # intended for transmission.
59
60 return ((cols / TAB_WIDTH) * '\t') + ((cols % TAB_WIDTH) * ' ')
61
62
63
64def pprint(seq, stream = None, indent = 0, allowance = 0):
65 """Pretty-print a list, tuple, or dictionary.
66
67 pprint(seq [, stream]) ==> None
68
69 If STREAM is provided, output is written to that stream, otherwise
70 sys.stdout is used. Indentation is done according to
71 INDENT_PER_LEVEL, which may be set to any non-negative integer
72 before calling this function. The output written on the stream is
73 a perfectly valid representation of the Python object passed in,
74 with indentation to suite human-readable interpretation. The
75 output can be used as input without error, given readable
76 representations of all sequence elements are available via repr().
77 Output is restricted to MAX_WIDTH columns where possible. The
78 STREAM parameter must support the write() method with a single
79 parameter, which will always be a string. The output stream may be
80 a StringIO.StringIO object if the result is needed as a string.
81 """
82
83 if stream is None:
84 import sys
85 stream = sys.stdout
86
87 from types import DictType, ListType, TupleType
88
89 rep = `seq`
90 typ = type(seq)
91 sepLines = len(rep) > (MAX_WIDTH - 1 - indent - allowance)
92
93 if sepLines and (typ is ListType or typ is TupleType):
94 # Pretty-print the sequence.
95 stream.write(((typ is ListType) and '[') or '(')
96
97 length = len(seq)
98 if length:
99 indent = indent + INDENT_PER_LEVEL
100 pprint(seq[0], stream, indent, allowance + 1)
101
102 if len(seq) > 1:
103 for ent in seq[1:]:
104 stream.write(',\n' + _indentation(indent))
105 pprint(ent, stream, indent, allowance + 1)
106
107 indent = indent - INDENT_PER_LEVEL
108
109 stream.write(((typ is ListType) and ']') or ')')
110
111 elif typ is DictType and sepLines:
112 stream.write('{')
113
114 length = len(seq)
115 if length:
116 indent = indent + INDENT_PER_LEVEL
117 items = seq.items()
118 items.sort()
119 key, ent = items[0]
120 rep = `key` + ': '
121 stream.write(rep)
122 pprint(ent, stream, indent + len(rep), allowance + 1)
123
124 if len(items) > 1:
125 for key, ent in items[1:]:
126 rep = `key` + ': '
127 stream.write(',\n' + _indentation(indent) + rep)
128 pprint(ent, stream, indent + len(rep), allowance + 1)
129
130 indent = indent - INDENT_PER_LEVEL
131
132 stream.write('}')
133
134 else:
135 stream.write(rep)
136
137 # Terminate the 'print' if we're not a recursive invocation.
138 if not indent:
139 stream.write('\n')
140
141
142#
143# end of pprint.py