blob: 36d188805bc1f666fab500e1c3126a9cf0249770 [file] [log] [blame]
Guido van Rossum16d27e31996-08-21 16:28:53 +00001# pprint.py
2#
3# Author: Fred L. Drake, Jr.
Guido van Rossum8206fb91996-08-26 00:33:29 +00004# fdrake@cnri.reston.va.us, fdrake@intr.net
Guido van Rossum16d27e31996-08-21 16:28:53 +00005#
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.
Guido van Rossum16d27e31996-08-21 16:28:53 +000012
13"""Support to pretty-print lists, tuples, & dictionaries recursively.
Guido van Rossum8206fb91996-08-26 00:33:29 +000014Very simple, but useful, especially in debugging data structures.
Guido van Rossum16d27e31996-08-21 16:28:53 +000015
Guido van Rossum8206fb91996-08-26 00:33:29 +000016Constants
17---------
Guido van Rossum16d27e31996-08-21 16:28:53 +000018
Guido van Rossum8206fb91996-08-26 00:33:29 +000019INDENT_PER_LEVEL
20 Amount of indentation to use for each new recursive level. The
21 default is 1. This must be a non-negative integer, and may be set
22 by the caller before calling pprint().
Guido van Rossum16d27e31996-08-21 16:28:53 +000023
Guido van Rossum8206fb91996-08-26 00:33:29 +000024MAX_WIDTH
25 Maximum width of the display. This is only used if the
26 representation *can* be kept less than MAX_WIDTH characters wide.
27 May be set by the user before calling pprint().
Guido van Rossum16d27e31996-08-21 16:28:53 +000028
Guido van Rossum8206fb91996-08-26 00:33:29 +000029TAB_WIDTH
30 The width represented by a single tab. This value is typically 8,
31 but 4 is the default under MacOS. Can be changed by the user if
32 desired, but is probably not a good idea.
Guido van Rossum16d27e31996-08-21 16:28:53 +000033"""
34
Guido van Rossum16d27e31996-08-21 16:28:53 +000035INDENT_PER_LEVEL = 1
36
37MAX_WIDTH = 80
38
39import os
40TAB_WIDTH = (os.name == 'mac' and 4) or 8
41del os
42
Guido van Rossum8206fb91996-08-26 00:33:29 +000043from types import DictType, ListType, TupleType
Guido van Rossum16d27e31996-08-21 16:28:53 +000044
45
46def _indentation(cols):
Guido van Rossum8206fb91996-08-26 00:33:29 +000047 """Create tabbed indentation string.
Guido van Rossum16d27e31996-08-21 16:28:53 +000048
Guido van Rossum8206fb91996-08-26 00:33:29 +000049 cols
50 Width of the indentation, in columns.
51 """
Guido van Rossum16d27e31996-08-21 16:28:53 +000052 return ((cols / TAB_WIDTH) * '\t') + ((cols % TAB_WIDTH) * ' ')
53
54
Guido van Rossum16d27e31996-08-21 16:28:53 +000055def pprint(seq, stream = None, indent = 0, allowance = 0):
56 """Pretty-print a list, tuple, or dictionary.
57
Guido van Rossum8206fb91996-08-26 00:33:29 +000058 seq
59 List, tuple, or dictionary object to be pretty-printed. Other
60 object types are permitted by are not specially interpreted.
Guido van Rossum16d27e31996-08-21 16:28:53 +000061
Guido van Rossum8206fb91996-08-26 00:33:29 +000062 stream
63 Output stream. If not provided, `sys.stdout' is used. This
64 parameter must support the `write()' method with a single
65 parameter, which will always be a string. It may be a
66 `StringIO.StringIO' object if the result is needed as a
67 string.
68
69 Indentation is done according to `INDENT_PER_LEVEL', which may be
70 set to any non-negative integer before calling this function. The
71 output written on the stream is a perfectly valid representation
72 of the Python object passed in, with indentation to assist
73 human-readable interpretation. The output can be used as input
74 without error, given readable representations of all elements are
75 available via `repr()'. Output is restricted to `MAX_WIDTH'
76 columns where possible.
Guido van Rossum16d27e31996-08-21 16:28:53 +000077 """
Guido van Rossum16d27e31996-08-21 16:28:53 +000078 if stream is None:
79 import sys
80 stream = sys.stdout
81
Guido van Rossum16d27e31996-08-21 16:28:53 +000082 rep = `seq`
83 typ = type(seq)
84 sepLines = len(rep) > (MAX_WIDTH - 1 - indent - allowance)
85
86 if sepLines and (typ is ListType or typ is TupleType):
87 # Pretty-print the sequence.
88 stream.write(((typ is ListType) and '[') or '(')
89
90 length = len(seq)
91 if length:
92 indent = indent + INDENT_PER_LEVEL
93 pprint(seq[0], stream, indent, allowance + 1)
94
95 if len(seq) > 1:
96 for ent in seq[1:]:
97 stream.write(',\n' + _indentation(indent))
98 pprint(ent, stream, indent, allowance + 1)
99
100 indent = indent - INDENT_PER_LEVEL
101
102 stream.write(((typ is ListType) and ']') or ')')
103
104 elif typ is DictType and sepLines:
105 stream.write('{')
106
107 length = len(seq)
108 if length:
109 indent = indent + INDENT_PER_LEVEL
110 items = seq.items()
111 items.sort()
112 key, ent = items[0]
113 rep = `key` + ': '
114 stream.write(rep)
115 pprint(ent, stream, indent + len(rep), allowance + 1)
116
117 if len(items) > 1:
118 for key, ent in items[1:]:
119 rep = `key` + ': '
120 stream.write(',\n' + _indentation(indent) + rep)
121 pprint(ent, stream, indent + len(rep), allowance + 1)
122
123 indent = indent - INDENT_PER_LEVEL
124
125 stream.write('}')
126
127 else:
128 stream.write(rep)
129
130 # Terminate the 'print' if we're not a recursive invocation.
131 if not indent:
132 stream.write('\n')
133
134
135#
Guido van Rossum8206fb91996-08-26 00:33:29 +0000136# end of file