Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / devtools / v8plus / lib / python2.4 / pprint.py
CommitLineData
920dae64
AT
1# Author: Fred L. Drake, Jr.
2# fdrake@acm.org
3#
4# This is a simple little module I wrote to make life easier. I didn't
5# see anything quite like it in the library, though I may have overlooked
6# something. I wrote this when I was trying to read some heavily nested
7# tuples with fairly non-descriptive content. This is modeled very much
8# after Lisp/Scheme - style pretty-printing of lists. If you find it
9# useful, thank small children who sleep at night.
10
11"""Support to pretty-print lists, tuples, & dictionaries recursively.
12
13Very simple, but useful, especially in debugging data structures.
14
15Classes
16-------
17
18PrettyPrinter()
19 Handle pretty-printing operations onto a stream using a configured
20 set of formatting parameters.
21
22Functions
23---------
24
25pformat()
26 Format a Python object into a pretty-printed representation.
27
28pprint()
29 Pretty-print a Python object to a stream [default is sys.stdout].
30
31saferepr()
32 Generate a 'standard' repr()-like value, but protect against recursive
33 data structures.
34
35"""
36
37import sys as _sys
38
39from cStringIO import StringIO as _StringIO
40
41__all__ = ["pprint","pformat","isreadable","isrecursive","saferepr",
42 "PrettyPrinter"]
43
44# cache these for faster access:
45_commajoin = ", ".join
46_id = id
47_len = len
48_type = type
49
50
51def pprint(object, stream=None, indent=1, width=80, depth=None):
52 """Pretty-print a Python object to a stream [default is sys.stdout]."""
53 printer = PrettyPrinter(
54 stream=stream, indent=indent, width=width, depth=depth)
55 printer.pprint(object)
56
57def pformat(object, indent=1, width=80, depth=None):
58 """Format a Python object into a pretty-printed representation."""
59 return PrettyPrinter(indent=indent, width=width, depth=depth).pformat(object)
60
61def saferepr(object):
62 """Version of repr() which can handle recursive data structures."""
63 return _safe_repr(object, {}, None, 0)[0]
64
65def isreadable(object):
66 """Determine if saferepr(object) is readable by eval()."""
67 return _safe_repr(object, {}, None, 0)[1]
68
69def isrecursive(object):
70 """Determine if object requires a recursive representation."""
71 return _safe_repr(object, {}, None, 0)[2]
72
73class PrettyPrinter:
74 def __init__(self, indent=1, width=80, depth=None, stream=None):
75 """Handle pretty printing operations onto a stream using a set of
76 configured parameters.
77
78 indent
79 Number of spaces to indent for each level of nesting.
80
81 width
82 Attempted maximum number of columns in the output.
83
84 depth
85 The maximum depth to print out nested structures.
86
87 stream
88 The desired output stream. If omitted (or false), the standard
89 output stream available at construction will be used.
90
91 """
92 indent = int(indent)
93 width = int(width)
94 assert indent >= 0, "indent must be >= 0"
95 assert depth is None or depth > 0, "depth must be > 0"
96 assert width, "width must be != 0"
97 self._depth = depth
98 self._indent_per_level = indent
99 self._width = width
100 if stream is not None:
101 self._stream = stream
102 else:
103 self._stream = _sys.stdout
104
105 def pprint(self, object):
106 self._stream.write(self.pformat(object) + "\n")
107
108 def pformat(self, object):
109 sio = _StringIO()
110 self._format(object, sio, 0, 0, {}, 0)
111 return sio.getvalue()
112
113 def isrecursive(self, object):
114 return self.format(object, {}, 0, 0)[2]
115
116 def isreadable(self, object):
117 s, readable, recursive = self.format(object, {}, 0, 0)
118 return readable and not recursive
119
120 def _format(self, object, stream, indent, allowance, context, level):
121 level = level + 1
122 objid = _id(object)
123 if objid in context:
124 stream.write(_recursion(object))
125 self._recursive = True
126 self._readable = False
127 return
128 rep = self._repr(object, context, level - 1)
129 typ = _type(object)
130 sepLines = _len(rep) > (self._width - 1 - indent - allowance)
131 write = stream.write
132
133 if sepLines:
134 r = getattr(typ, "__repr__", None)
135 if issubclass(typ, dict) and r is dict.__repr__:
136 write('{')
137 if self._indent_per_level > 1:
138 write((self._indent_per_level - 1) * ' ')
139 length = _len(object)
140 if length:
141 context[objid] = 1
142 indent = indent + self._indent_per_level
143 items = object.items()
144 items.sort()
145 key, ent = items[0]
146 rep = self._repr(key, context, level)
147 write(rep)
148 write(': ')
149 self._format(ent, stream, indent + _len(rep) + 2,
150 allowance + 1, context, level)
151 if length > 1:
152 for key, ent in items[1:]:
153 rep = self._repr(key, context, level)
154 write(',\n%s%s: ' % (' '*indent, rep))
155 self._format(ent, stream, indent + _len(rep) + 2,
156 allowance + 1, context, level)
157 indent = indent - self._indent_per_level
158 del context[objid]
159 write('}')
160 return
161
162 if (issubclass(typ, list) and r is list.__repr__) or \
163 (issubclass(typ, tuple) and r is tuple.__repr__):
164 if issubclass(typ, list):
165 write('[')
166 endchar = ']'
167 else:
168 write('(')
169 endchar = ')'
170 if self._indent_per_level > 1:
171 write((self._indent_per_level - 1) * ' ')
172 length = _len(object)
173 if length:
174 context[objid] = 1
175 indent = indent + self._indent_per_level
176 self._format(object[0], stream, indent, allowance + 1,
177 context, level)
178 if length > 1:
179 for ent in object[1:]:
180 write(',\n' + ' '*indent)
181 self._format(ent, stream, indent,
182 allowance + 1, context, level)
183 indent = indent - self._indent_per_level
184 del context[objid]
185 if issubclass(typ, tuple) and length == 1:
186 write(',')
187 write(endchar)
188 return
189
190 write(rep)
191
192 def _repr(self, object, context, level):
193 repr, readable, recursive = self.format(object, context.copy(),
194 self._depth, level)
195 if not readable:
196 self._readable = False
197 if recursive:
198 self._recursive = True
199 return repr
200
201 def format(self, object, context, maxlevels, level):
202 """Format object for a specific context, returning a string
203 and flags indicating whether the representation is 'readable'
204 and whether the object represents a recursive construct.
205 """
206 return _safe_repr(object, context, maxlevels, level)
207
208
209# Return triple (repr_string, isreadable, isrecursive).
210
211def _safe_repr(object, context, maxlevels, level):
212 typ = _type(object)
213 if typ is str:
214 if 'locale' not in _sys.modules:
215 return repr(object), True, False
216 if "'" in object and '"' not in object:
217 closure = '"'
218 quotes = {'"': '\\"'}
219 else:
220 closure = "'"
221 quotes = {"'": "\\'"}
222 qget = quotes.get
223 sio = _StringIO()
224 write = sio.write
225 for char in object:
226 if char.isalpha():
227 write(char)
228 else:
229 write(qget(char, repr(char)[1:-1]))
230 return ("%s%s%s" % (closure, sio.getvalue(), closure)), True, False
231
232 r = getattr(typ, "__repr__", None)
233 if issubclass(typ, dict) and r is dict.__repr__:
234 if not object:
235 return "{}", True, False
236 objid = _id(object)
237 if maxlevels and level > maxlevels:
238 return "{...}", False, objid in context
239 if objid in context:
240 return _recursion(object), False, True
241 context[objid] = 1
242 readable = True
243 recursive = False
244 components = []
245 append = components.append
246 level += 1
247 saferepr = _safe_repr
248 for k, v in object.iteritems():
249 krepr, kreadable, krecur = saferepr(k, context, maxlevels, level)
250 vrepr, vreadable, vrecur = saferepr(v, context, maxlevels, level)
251 append("%s: %s" % (krepr, vrepr))
252 readable = readable and kreadable and vreadable
253 if krecur or vrecur:
254 recursive = True
255 del context[objid]
256 return "{%s}" % _commajoin(components), readable, recursive
257
258 if (issubclass(typ, list) and r is list.__repr__) or \
259 (issubclass(typ, tuple) and r is tuple.__repr__):
260 if issubclass(typ, list):
261 if not object:
262 return "[]", True, False
263 format = "[%s]"
264 elif _len(object) == 1:
265 format = "(%s,)"
266 else:
267 if not object:
268 return "()", True, False
269 format = "(%s)"
270 objid = _id(object)
271 if maxlevels and level > maxlevels:
272 return format % "...", False, objid in context
273 if objid in context:
274 return _recursion(object), False, True
275 context[objid] = 1
276 readable = True
277 recursive = False
278 components = []
279 append = components.append
280 level += 1
281 for o in object:
282 orepr, oreadable, orecur = _safe_repr(o, context, maxlevels, level)
283 append(orepr)
284 if not oreadable:
285 readable = False
286 if orecur:
287 recursive = True
288 del context[objid]
289 return format % _commajoin(components), readable, recursive
290
291 rep = repr(object)
292 return rep, (rep and not rep.startswith('<')), False
293
294
295def _recursion(object):
296 return ("<Recursion on %s with id=%s>"
297 % (_type(object).__name__, _id(object)))
298
299
300def _perfcheck(object=None):
301 import time
302 if object is None:
303 object = [("string", (1, 2), [3, 4], {5: 6, 7: 8})] * 100000
304 p = PrettyPrinter()
305 t1 = time.time()
306 _safe_repr(object, {}, None, 0)
307 t2 = time.time()
308 p.pformat(object)
309 t3 = time.time()
310 print "_safe_repr:", t2 - t1
311 print "pformat:", t3 - t2
312
313if __name__ == "__main__":
314 _perfcheck()