Vega strike Python Modules doc  0.5.1
Documentation of the " Modules " folder of Vega strike
 All Data Structures Namespaces Files Functions Variables
pprint.py
Go to the documentation of this file.
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 
13 Very simple, but useful, especially in debugging data structures.
14 
15 Classes
16 -------
17 
18 PrettyPrinter()
19  Handle pretty-printing operations onto a stream using a configured
20  set of formatting parameters.
21 
22 Functions
23 ---------
24 
25 pformat()
26  Format a Python object into a pretty-printed representation.
27 
28 pprint()
29  Pretty-print a Python object to a stream [default is sys.sydout].
30 
31 saferepr()
32  Generate a 'standard' repr()-like value, but protect against recursive
33  data structures.
34 
35 """
36 
37 from types import DictType, ListType, TupleType, StringType
38 import sys
39 
40 try:
41  from cStringIO import StringIO
42 except ImportError:
43  from StringIO import StringIO
44 
45 __all__ = ["pprint","pformat","isreadable","isrecursive","saferepr",
46  "PrettyPrinter"]
47 
48 # cache these for faster access:
49 _commajoin = ", ".join
50 _sys_modules = sys.modules
51 _id = id
52 _len = len
53 _type = type
54 
55 
56 def pprint(object, stream=None):
57  """Pretty-print a Python object to a stream [default is sys.sydout]."""
58  printer = PrettyPrinter(stream=stream)
59  printer.pprint(object)
60 
61 def pformat(object):
62  """Format a Python object into a pretty-printed representation."""
63  return PrettyPrinter().pformat(object)
64 
65 def saferepr(object):
66  """Version of repr() which can handle recursive data structures."""
67  return _safe_repr(object, {}, None, 0)[0]
68 
69 def isreadable(object):
70  """Determine if saferepr(object) is readable by eval()."""
71  return _safe_repr(object, {}, None, 0)[1]
72 
73 def isrecursive(object):
74  """Determine if object requires a recursive representation."""
75  return _safe_repr(object, {}, None, 0)[2]
76 
78  def __init__(self, indent=1, width=80, depth=None, stream=None):
79  """Handle pretty printing operations onto a stream using a set of
80  configured parameters.
81 
82  indent
83  Number of spaces to indent for each level of nesting.
84 
85  width
86  Attempted maximum number of columns in the output.
87 
88  depth
89  The maximum depth to print out nested structures.
90 
91  stream
92  The desired output stream. If omitted (or false), the standard
93  output stream available at construction will be used.
94 
95  """
96  indent = int(indent)
97  width = int(width)
98  assert indent >= 0
99  assert depth is None or depth > 0, "depth must be > 0"
100  assert width
101  self.__depth = depth
102  self.__indent_per_level = indent
103  self.__width = width
104  if stream:
105  self.__stream = stream
106  else:
107  self.__stream = sys.stdout
108 
109  def pprint(self, object):
110  self.__stream.write(self.pformat(object) + "\n")
111 
112  def pformat(self, object):
113  sio = StringIO()
114  self.__format(object, sio, 0, 0, {}, 0)
115  return sio.getvalue()
116 
117  def isrecursive(self, object):
118  self.__recursive = 0
119  self.__repr(object, {}, 0)
120  return self.__recursive
121 
122  def isreadable(self, object):
123  self.__recursive = 0
124  self.__readable = 1
125  self.__repr(object, {}, 0)
126  return self.__readable and not self.__recursive
127 
128  def __format(self, object, stream, indent, allowance, context, level):
129  level = level + 1
130  objid = _id(object)
131  if objid in context:
132  stream.write(_recursion(object))
133  self.__recursive = 1
134  self.__readable = 0
135  return
136  rep = self.__repr(object, context, level - 1)
137  typ = _type(object)
138  sepLines = _len(rep) > (self.__width - 1 - indent - allowance)
139  write = stream.write
140 
141  if sepLines:
142  if typ is DictType:
143  write('{')
144  if self.__indent_per_level > 1:
145  write((self.__indent_per_level - 1) * ' ')
146  length = _len(object)
147  if length:
148  context[objid] = 1
149  indent = indent + self.__indent_per_level
150  items = object.items()
151  items.sort()
152  key, ent = items[0]
153  rep = self.__repr(key, context, level)
154  write(rep)
155  write(': ')
156  self.__format(ent, stream, indent + _len(rep) + 2,
157  allowance + 1, context, level)
158  if length > 1:
159  for key, ent in items[1:]:
160  rep = self.__repr(key, context, level)
161  write(',\n%s%s: ' % (' '*indent, rep))
162  self.__format(ent, stream, indent + _len(rep) + 2,
163  allowance + 1, context, level)
164  indent = indent - self.__indent_per_level
165  del context[objid]
166  write('}')
167  return
168 
169  if typ is ListType or typ is TupleType:
170  if typ is ListType:
171  write('[')
172  endchar = ']'
173  else:
174  write('(')
175  endchar = ')'
176  if self.__indent_per_level > 1:
177  write((self.__indent_per_level - 1) * ' ')
178  length = _len(object)
179  if length:
180  context[objid] = 1
181  indent = indent + self.__indent_per_level
182  self.__format(object[0], stream, indent, allowance + 1,
183  context, level)
184  if length > 1:
185  for ent in object[1:]:
186  write(',\n' + ' '*indent)
187  self.__format(ent, stream, indent,
188  allowance + 1, context, level)
189  indent = indent - self.__indent_per_level
190  del context[objid]
191  if typ is TupleType and length == 1:
192  write(',')
193  write(endchar)
194  return
195 
196  write(rep)
197 
198  def __repr(self, object, context, level):
199  repr, readable, recursive = _safe_repr(object, context,
200  self.__depth, level)
201  if not readable:
202  self.__readable = 0
203  if recursive:
204  self.__recursive = 1
205  return repr
206 
207 # Return triple (repr_string, isreadable, isrecursive).
208 
209 def _safe_repr(object, context, maxlevels, level):
210  typ = _type(object)
211  if typ is StringType:
212  if 'locale' not in _sys_modules:
213  return `object`, 1, 0
214  if "'" in object and '"' not in object:
215  closure = '"'
216  quotes = {'"': '\\"'}
217  else:
218  closure = "'"
219  quotes = {"'": "\\'"}
220  qget = quotes.get
221  sio = StringIO()
222  write = sio.write
223  for char in object:
224  if char.isalpha():
225  write(char)
226  else:
227  write(qget(char, `char`[1:-1]))
228  return ("%s%s%s" % (closure, sio.getvalue(), closure)), 1, 0
229 
230  if typ is DictType:
231  if not object:
232  return "{}", 1, 0
233  objid = _id(object)
234  if maxlevels and level > maxlevels:
235  return "{...}", 0, objid in context
236  if objid in context:
237  return _recursion(object), 0, 1
238  context[objid] = 1
239  readable = 1
240  recursive = 0
241  components = []
242  append = components.append
243  level += 1
244  saferepr = _safe_repr
245  for k, v in object.iteritems():
246  krepr, kreadable, krecur = saferepr(k, context, maxlevels, level)
247  vrepr, vreadable, vrecur = saferepr(v, context, maxlevels, level)
248  append("%s: %s" % (krepr, vrepr))
249  readable = readable and kreadable and vreadable
250  if krecur or vrecur:
251  recursive = 1
252  del context[objid]
253  return "{%s}" % _commajoin(components), readable, recursive
254 
255  if typ is ListType or typ is TupleType:
256  if typ is ListType:
257  if not object:
258  return "[]", 1, 0
259  format = "[%s]"
260  elif _len(object) == 1:
261  format = "(%s,)"
262  else:
263  if not object:
264  return "()", 1, 0
265  format = "(%s)"
266  objid = _id(object)
267  if maxlevels and level > maxlevels:
268  return format % "...", 0, objid in context
269  if objid in context:
270  return _recursion(object), 0, 1
271  context[objid] = 1
272  readable = 1
273  recursive = 0
274  components = []
275  append = components.append
276  level += 1
277  for o in object:
278  orepr, oreadable, orecur = _safe_repr(o, context, maxlevels, level)
279  append(orepr)
280  if not oreadable:
281  readable = 0
282  if orecur:
283  recursive = 1
284  del context[objid]
285  return format % _commajoin(components), readable, recursive
286 
287  rep = `object`
288  return rep, (rep and not rep.startswith('<')), 0
289 
290 
291 def _recursion(object):
292  return ("<Recursion on %s with id=%s>"
293  % (_type(object).__name__, _id(object)))
294 
295 
296 def _perfcheck(object=None):
297  import time
298  if object is None:
299  object = [("string", (1, 2), [3, 4], {5: 6, 7: 8})] * 100000
300  p = PrettyPrinter()
301  t1 = time.time()
302  _safe_repr(object, {}, None, 0)
303  t2 = time.time()
304  p.pformat(object)
305  t3 = time.time()
306  print "_safe_repr:", t2 - t1
307  print "pformat:", t3 - t2
308 
309 if __name__ == "__main__":
310  _perfcheck()