##// END OF EJS Templates
BUG: For subclasses of tuple, list, dict, set, and frozenset, only use the pretty-printer if the subclasses do not replace the base class's __repr__.
Robert Kern -
Show More
@@ -1,700 +1,710 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 pretty
3 pretty
4 ~~
4 ~~
5
5
6 Python advanced pretty printer. This pretty printer is intended to
6 Python advanced pretty printer. This pretty printer is intended to
7 replace the old `pprint` python module which does not allow developers
7 replace the old `pprint` python module which does not allow developers
8 to provide their own pretty print callbacks.
8 to provide their own pretty print callbacks.
9
9
10 This module is based on ruby's `prettyprint.rb` library by `Tanaka Akira`.
10 This module is based on ruby's `prettyprint.rb` library by `Tanaka Akira`.
11
11
12
12
13 Example Usage
13 Example Usage
14 =============
14 =============
15
15
16 To directly print the representation of an object use `pprint`::
16 To directly print the representation of an object use `pprint`::
17
17
18 from pretty import pprint
18 from pretty import pprint
19 pprint(complex_object)
19 pprint(complex_object)
20
20
21 To get a string of the output use `pretty`::
21 To get a string of the output use `pretty`::
22
22
23 from pretty import pretty
23 from pretty import pretty
24 string = pretty(complex_object)
24 string = pretty(complex_object)
25
25
26
26
27 Extending
27 Extending
28 =========
28 =========
29
29
30 The pretty library allows developers to add pretty printing rules for their
30 The pretty library allows developers to add pretty printing rules for their
31 own objects. This process is straightforward. All you have to do is to
31 own objects. This process is straightforward. All you have to do is to
32 add a `__pretty__` method to your object and call the methods on the
32 add a `__pretty__` method to your object and call the methods on the
33 pretty printer passed::
33 pretty printer passed::
34
34
35 class MyObject(object):
35 class MyObject(object):
36
36
37 def __pretty__(self, p, cycle):
37 def __pretty__(self, p, cycle):
38 ...
38 ...
39
39
40 Depending on the python version you want to support you have two
40 Depending on the python version you want to support you have two
41 possibilities. The following list shows the python 2.5 version and the
41 possibilities. The following list shows the python 2.5 version and the
42 compatibility one.
42 compatibility one.
43
43
44
44
45 Here the example implementation of a `__pretty__` method for a list
45 Here the example implementation of a `__pretty__` method for a list
46 subclass for python 2.5 and higher (python 2.5 requires the with statement
46 subclass for python 2.5 and higher (python 2.5 requires the with statement
47 __future__ import)::
47 __future__ import)::
48
48
49 class MyList(list):
49 class MyList(list):
50
50
51 def __pretty__(self, p, cycle):
51 def __pretty__(self, p, cycle):
52 if cycle:
52 if cycle:
53 p.text('MyList(...)')
53 p.text('MyList(...)')
54 else:
54 else:
55 with p.group(8, 'MyList([', '])'):
55 with p.group(8, 'MyList([', '])'):
56 for idx, item in enumerate(self):
56 for idx, item in enumerate(self):
57 if idx:
57 if idx:
58 p.text(',')
58 p.text(',')
59 p.breakable()
59 p.breakable()
60 p.pretty(item)
60 p.pretty(item)
61
61
62 The `cycle` parameter is `True` if pretty detected a cycle. You *have* to
62 The `cycle` parameter is `True` if pretty detected a cycle. You *have* to
63 react to that or the result is an infinite loop. `p.text()` just adds
63 react to that or the result is an infinite loop. `p.text()` just adds
64 non breaking text to the output, `p.breakable()` either adds a whitespace
64 non breaking text to the output, `p.breakable()` either adds a whitespace
65 or breaks here. If you pass it an argument it's used instead of the
65 or breaks here. If you pass it an argument it's used instead of the
66 default space. `p.pretty` prettyprints another object using the pretty print
66 default space. `p.pretty` prettyprints another object using the pretty print
67 method.
67 method.
68
68
69 The first parameter to the `group` function specifies the extra indentation
69 The first parameter to the `group` function specifies the extra indentation
70 of the next line. In this example the next item will either be not
70 of the next line. In this example the next item will either be not
71 breaked (if the items are short enough) or aligned with the right edge of
71 breaked (if the items are short enough) or aligned with the right edge of
72 the opening bracked of `MyList`.
72 the opening bracked of `MyList`.
73
73
74 If you want to support python 2.4 and lower you can use this code::
74 If you want to support python 2.4 and lower you can use this code::
75
75
76 class MyList(list):
76 class MyList(list):
77
77
78 def __pretty__(self, p, cycle):
78 def __pretty__(self, p, cycle):
79 if cycle:
79 if cycle:
80 p.text('MyList(...)')
80 p.text('MyList(...)')
81 else:
81 else:
82 p.begin_group(8, 'MyList([')
82 p.begin_group(8, 'MyList([')
83 for idx, item in enumerate(self):
83 for idx, item in enumerate(self):
84 if idx:
84 if idx:
85 p.text(',')
85 p.text(',')
86 p.breakable()
86 p.breakable()
87 p.pretty(item)
87 p.pretty(item)
88 p.end_group(8, '])')
88 p.end_group(8, '])')
89
89
90 If you just want to indent something you can use the group function
90 If you just want to indent something you can use the group function
91 without open / close parameters. Under python 2.5 you can also use this
91 without open / close parameters. Under python 2.5 you can also use this
92 code::
92 code::
93
93
94 with p.indent(2):
94 with p.indent(2):
95 ...
95 ...
96
96
97 Or under python2.4 you might want to modify ``p.indentation`` by hand but
97 Or under python2.4 you might want to modify ``p.indentation`` by hand but
98 this is rather ugly.
98 this is rather ugly.
99
99
100 :copyright: 2007 by Armin Ronacher.
100 :copyright: 2007 by Armin Ronacher.
101 Portions (c) 2009 by Robert Kern.
101 Portions (c) 2009 by Robert Kern.
102 :license: BSD License.
102 :license: BSD License.
103 """
103 """
104 from __future__ import with_statement
104 from __future__ import with_statement
105 from contextlib import contextmanager
105 from contextlib import contextmanager
106 import sys
106 import sys
107 import types
107 import types
108 import re
108 import re
109 import datetime
109 import datetime
110 from StringIO import StringIO
110 from StringIO import StringIO
111 from collections import deque
111 from collections import deque
112
112
113
113
114 __all__ = ['pretty', 'pprint', 'PrettyPrinter', 'RepresentationPrinter',
114 __all__ = ['pretty', 'pprint', 'PrettyPrinter', 'RepresentationPrinter',
115 'for_type', 'for_type_by_name']
115 'for_type', 'for_type_by_name']
116
116
117
117
118 _re_pattern_type = type(re.compile(''))
118 _re_pattern_type = type(re.compile(''))
119
119
120
120
121 def pretty(obj, verbose=False, max_width=79, newline='\n'):
121 def pretty(obj, verbose=False, max_width=79, newline='\n'):
122 """
122 """
123 Pretty print the object's representation.
123 Pretty print the object's representation.
124 """
124 """
125 stream = StringIO()
125 stream = StringIO()
126 printer = RepresentationPrinter(stream, verbose, max_width, newline)
126 printer = RepresentationPrinter(stream, verbose, max_width, newline)
127 printer.pretty(obj)
127 printer.pretty(obj)
128 printer.flush()
128 printer.flush()
129 return stream.getvalue()
129 return stream.getvalue()
130
130
131
131
132 def pprint(obj, verbose=False, max_width=79, newline='\n'):
132 def pprint(obj, verbose=False, max_width=79, newline='\n'):
133 """
133 """
134 Like `pretty` but print to stdout.
134 Like `pretty` but print to stdout.
135 """
135 """
136 printer = RepresentationPrinter(sys.stdout, verbose, max_width, newline)
136 printer = RepresentationPrinter(sys.stdout, verbose, max_width, newline)
137 printer.pretty(obj)
137 printer.pretty(obj)
138 printer.flush()
138 printer.flush()
139 sys.stdout.write(newline)
139 sys.stdout.write(newline)
140 sys.stdout.flush()
140 sys.stdout.flush()
141
141
142 class _PrettyPrinterBase(object):
142 class _PrettyPrinterBase(object):
143
143
144 @contextmanager
144 @contextmanager
145 def indent(self, indent):
145 def indent(self, indent):
146 """with statement support for indenting/dedenting."""
146 """with statement support for indenting/dedenting."""
147 self.indentation += indent
147 self.indentation += indent
148 try:
148 try:
149 yield
149 yield
150 finally:
150 finally:
151 self.indentation -= indent
151 self.indentation -= indent
152
152
153 @contextmanager
153 @contextmanager
154 def group(self, indent=0, open='', close=''):
154 def group(self, indent=0, open='', close=''):
155 """like begin_group / end_group but for the with statement."""
155 """like begin_group / end_group but for the with statement."""
156 self.begin_group(indent, open)
156 self.begin_group(indent, open)
157 try:
157 try:
158 with self.indent(indent):
158 with self.indent(indent):
159 yield
159 yield
160 finally:
160 finally:
161 self.end_group(indent, close)
161 self.end_group(indent, close)
162
162
163 class PrettyPrinter(_PrettyPrinterBase):
163 class PrettyPrinter(_PrettyPrinterBase):
164 """
164 """
165 Baseclass for the `RepresentationPrinter` prettyprinter that is used to
165 Baseclass for the `RepresentationPrinter` prettyprinter that is used to
166 generate pretty reprs of objects. Contrary to the `RepresentationPrinter`
166 generate pretty reprs of objects. Contrary to the `RepresentationPrinter`
167 this printer knows nothing about the default pprinters or the `__pretty__`
167 this printer knows nothing about the default pprinters or the `__pretty__`
168 callback method.
168 callback method.
169 """
169 """
170
170
171 def __init__(self, output, max_width=79, newline='\n'):
171 def __init__(self, output, max_width=79, newline='\n'):
172 self.output = output
172 self.output = output
173 self.max_width = max_width
173 self.max_width = max_width
174 self.newline = newline
174 self.newline = newline
175 self.output_width = 0
175 self.output_width = 0
176 self.buffer_width = 0
176 self.buffer_width = 0
177 self.buffer = deque()
177 self.buffer = deque()
178
178
179 root_group = Group(0)
179 root_group = Group(0)
180 self.group_stack = [root_group]
180 self.group_stack = [root_group]
181 self.group_queue = GroupQueue(root_group)
181 self.group_queue = GroupQueue(root_group)
182 self.indentation = 0
182 self.indentation = 0
183
183
184 def _break_outer_groups(self):
184 def _break_outer_groups(self):
185 while self.max_width < self.output_width + self.buffer_width:
185 while self.max_width < self.output_width + self.buffer_width:
186 group = self.group_queue.deq()
186 group = self.group_queue.deq()
187 if not group:
187 if not group:
188 return
188 return
189 while group.breakables:
189 while group.breakables:
190 x = self.buffer.popleft()
190 x = self.buffer.popleft()
191 self.output_width = x.output(self.output, self.output_width)
191 self.output_width = x.output(self.output, self.output_width)
192 self.buffer_width -= x.width
192 self.buffer_width -= x.width
193 while self.buffer and isinstance(self.buffer[0], Text):
193 while self.buffer and isinstance(self.buffer[0], Text):
194 x = self.buffer.popleft()
194 x = self.buffer.popleft()
195 self.output_width = x.output(self.output, self.output_width)
195 self.output_width = x.output(self.output, self.output_width)
196 self.buffer_width -= x.width
196 self.buffer_width -= x.width
197
197
198 def text(self, obj):
198 def text(self, obj):
199 """Add literal text to the output."""
199 """Add literal text to the output."""
200 width = len(obj)
200 width = len(obj)
201 if self.buffer:
201 if self.buffer:
202 text = self.buffer[-1]
202 text = self.buffer[-1]
203 if not isinstance(text, Text):
203 if not isinstance(text, Text):
204 text = Text()
204 text = Text()
205 self.buffer.append(text)
205 self.buffer.append(text)
206 text.add(obj, width)
206 text.add(obj, width)
207 self.buffer_width += width
207 self.buffer_width += width
208 self._break_outer_groups()
208 self._break_outer_groups()
209 else:
209 else:
210 self.output.write(obj)
210 self.output.write(obj)
211 self.output_width += width
211 self.output_width += width
212
212
213 def breakable(self, sep=' '):
213 def breakable(self, sep=' '):
214 """
214 """
215 Add a breakable separator to the output. This does not mean that it
215 Add a breakable separator to the output. This does not mean that it
216 will automatically break here. If no breaking on this position takes
216 will automatically break here. If no breaking on this position takes
217 place the `sep` is inserted which default to one space.
217 place the `sep` is inserted which default to one space.
218 """
218 """
219 width = len(sep)
219 width = len(sep)
220 group = self.group_stack[-1]
220 group = self.group_stack[-1]
221 if group.want_break:
221 if group.want_break:
222 self.flush()
222 self.flush()
223 self.output.write(self.newline)
223 self.output.write(self.newline)
224 self.output.write(' ' * self.indentation)
224 self.output.write(' ' * self.indentation)
225 self.output_width = self.indentation
225 self.output_width = self.indentation
226 self.buffer_width = 0
226 self.buffer_width = 0
227 else:
227 else:
228 self.buffer.append(Breakable(sep, width, self))
228 self.buffer.append(Breakable(sep, width, self))
229 self.buffer_width += width
229 self.buffer_width += width
230 self._break_outer_groups()
230 self._break_outer_groups()
231
231
232
232
233 def begin_group(self, indent=0, open=''):
233 def begin_group(self, indent=0, open=''):
234 """
234 """
235 Begin a group. If you want support for python < 2.5 which doesn't has
235 Begin a group. If you want support for python < 2.5 which doesn't has
236 the with statement this is the preferred way:
236 the with statement this is the preferred way:
237
237
238 p.begin_group(1, '{')
238 p.begin_group(1, '{')
239 ...
239 ...
240 p.end_group(1, '}')
240 p.end_group(1, '}')
241
241
242 The python 2.5 expression would be this:
242 The python 2.5 expression would be this:
243
243
244 with p.group(1, '{', '}'):
244 with p.group(1, '{', '}'):
245 ...
245 ...
246
246
247 The first parameter specifies the indentation for the next line (usually
247 The first parameter specifies the indentation for the next line (usually
248 the width of the opening text), the second the opening text. All
248 the width of the opening text), the second the opening text. All
249 parameters are optional.
249 parameters are optional.
250 """
250 """
251 if open:
251 if open:
252 self.text(open)
252 self.text(open)
253 group = Group(self.group_stack[-1].depth + 1)
253 group = Group(self.group_stack[-1].depth + 1)
254 self.group_stack.append(group)
254 self.group_stack.append(group)
255 self.group_queue.enq(group)
255 self.group_queue.enq(group)
256 self.indentation += indent
256 self.indentation += indent
257
257
258 def end_group(self, dedent=0, close=''):
258 def end_group(self, dedent=0, close=''):
259 """End a group. See `begin_group` for more details."""
259 """End a group. See `begin_group` for more details."""
260 self.indentation -= dedent
260 self.indentation -= dedent
261 group = self.group_stack.pop()
261 group = self.group_stack.pop()
262 if not group.breakables:
262 if not group.breakables:
263 self.group_queue.remove(group)
263 self.group_queue.remove(group)
264 if close:
264 if close:
265 self.text(close)
265 self.text(close)
266
266
267 def flush(self):
267 def flush(self):
268 """Flush data that is left in the buffer."""
268 """Flush data that is left in the buffer."""
269 for data in self.buffer:
269 for data in self.buffer:
270 self.output_width += data.output(self.output, self.output_width)
270 self.output_width += data.output(self.output, self.output_width)
271 self.buffer.clear()
271 self.buffer.clear()
272 self.buffer_width = 0
272 self.buffer_width = 0
273
273
274
274
275 def _get_mro(obj_class):
275 def _get_mro(obj_class):
276 """ Get a reasonable method resolution order of a class and its superclasses
276 """ Get a reasonable method resolution order of a class and its superclasses
277 for both old-style and new-style classes.
277 for both old-style and new-style classes.
278 """
278 """
279 if not hasattr(obj_class, '__mro__'):
279 if not hasattr(obj_class, '__mro__'):
280 # Old-style class. Mix in object to make a fake new-style class.
280 # Old-style class. Mix in object to make a fake new-style class.
281 try:
281 try:
282 obj_class = type(obj_class.__name__, (obj_class, object), {})
282 obj_class = type(obj_class.__name__, (obj_class, object), {})
283 except TypeError:
283 except TypeError:
284 # Old-style extension type that does not descend from object.
284 # Old-style extension type that does not descend from object.
285 # FIXME: try to construct a more thorough MRO.
285 # FIXME: try to construct a more thorough MRO.
286 mro = [obj_class]
286 mro = [obj_class]
287 else:
287 else:
288 mro = obj_class.__mro__[1:-1]
288 mro = obj_class.__mro__[1:-1]
289 else:
289 else:
290 mro = obj_class.__mro__
290 mro = obj_class.__mro__
291 return mro
291 return mro
292
292
293
293
294 class RepresentationPrinter(PrettyPrinter):
294 class RepresentationPrinter(PrettyPrinter):
295 """
295 """
296 Special pretty printer that has a `pretty` method that calls the pretty
296 Special pretty printer that has a `pretty` method that calls the pretty
297 printer for a python object.
297 printer for a python object.
298
298
299 This class stores processing data on `self` so you must *never* use
299 This class stores processing data on `self` so you must *never* use
300 this class in a threaded environment. Always lock it or reinstanciate
300 this class in a threaded environment. Always lock it or reinstanciate
301 it.
301 it.
302
302
303 Instances also have a verbose flag callbacks can access to control their
303 Instances also have a verbose flag callbacks can access to control their
304 output. For example the default instance repr prints all attributes and
304 output. For example the default instance repr prints all attributes and
305 methods that are not prefixed by an underscore if the printer is in
305 methods that are not prefixed by an underscore if the printer is in
306 verbose mode.
306 verbose mode.
307 """
307 """
308
308
309 def __init__(self, output, verbose=False, max_width=79, newline='\n',
309 def __init__(self, output, verbose=False, max_width=79, newline='\n',
310 singleton_pprinters=None, type_pprinters=None, deferred_pprinters=None):
310 singleton_pprinters=None, type_pprinters=None, deferred_pprinters=None):
311
311
312 PrettyPrinter.__init__(self, output, max_width, newline)
312 PrettyPrinter.__init__(self, output, max_width, newline)
313 self.verbose = verbose
313 self.verbose = verbose
314 self.stack = []
314 self.stack = []
315 if singleton_pprinters is None:
315 if singleton_pprinters is None:
316 singleton_pprinters = _singleton_pprinters.copy()
316 singleton_pprinters = _singleton_pprinters.copy()
317 self.singleton_pprinters = singleton_pprinters
317 self.singleton_pprinters = singleton_pprinters
318 if type_pprinters is None:
318 if type_pprinters is None:
319 type_pprinters = _type_pprinters.copy()
319 type_pprinters = _type_pprinters.copy()
320 self.type_pprinters = type_pprinters
320 self.type_pprinters = type_pprinters
321 if deferred_pprinters is None:
321 if deferred_pprinters is None:
322 deferred_pprinters = _deferred_type_pprinters.copy()
322 deferred_pprinters = _deferred_type_pprinters.copy()
323 self.deferred_pprinters = deferred_pprinters
323 self.deferred_pprinters = deferred_pprinters
324
324
325 def pretty(self, obj):
325 def pretty(self, obj):
326 """Pretty print the given object."""
326 """Pretty print the given object."""
327 obj_id = id(obj)
327 obj_id = id(obj)
328 cycle = obj_id in self.stack
328 cycle = obj_id in self.stack
329 self.stack.append(obj_id)
329 self.stack.append(obj_id)
330 self.begin_group()
330 self.begin_group()
331 try:
331 try:
332 obj_class = getattr(obj, '__class__', None) or type(obj)
332 obj_class = getattr(obj, '__class__', None) or type(obj)
333 if hasattr(obj_class, '__pretty__'):
333 if hasattr(obj_class, '__pretty__'):
334 return obj_class.__pretty__(obj, self, cycle)
334 return obj_class.__pretty__(obj, self, cycle)
335 try:
335 try:
336 printer = self.singleton_pprinters[obj_id]
336 printer = self.singleton_pprinters[obj_id]
337 except (TypeError, KeyError):
337 except (TypeError, KeyError):
338 pass
338 pass
339 else:
339 else:
340 return printer(obj, self, cycle)
340 return printer(obj, self, cycle)
341 for cls in _get_mro(obj_class):
341 for cls in _get_mro(obj_class):
342 if cls in self.type_pprinters:
342 if cls in self.type_pprinters:
343 return self.type_pprinters[cls](obj, self, cycle)
343 return self.type_pprinters[cls](obj, self, cycle)
344 else:
344 else:
345 printer = self._in_deferred_types(cls)
345 printer = self._in_deferred_types(cls)
346 if printer is not None:
346 if printer is not None:
347 return printer(obj, self, cycle)
347 return printer(obj, self, cycle)
348 return _default_pprint(obj, self, cycle)
348 return _default_pprint(obj, self, cycle)
349 finally:
349 finally:
350 self.end_group()
350 self.end_group()
351 self.stack.pop()
351 self.stack.pop()
352
352
353 def _in_deferred_types(self, cls):
353 def _in_deferred_types(self, cls):
354 """
354 """
355 Check if the given class is specified in the deferred type registry.
355 Check if the given class is specified in the deferred type registry.
356
356
357 Returns the printer from the registry if it exists, and None if the
357 Returns the printer from the registry if it exists, and None if the
358 class is not in the registry. Successful matches will be moved to the
358 class is not in the registry. Successful matches will be moved to the
359 regular type registry for future use.
359 regular type registry for future use.
360 """
360 """
361 mod = getattr(cls, '__module__', None)
361 mod = getattr(cls, '__module__', None)
362 name = getattr(cls, '__name__', None)
362 name = getattr(cls, '__name__', None)
363 key = (mod, name)
363 key = (mod, name)
364 printer = None
364 printer = None
365 if key in self.deferred_pprinters:
365 if key in self.deferred_pprinters:
366 # Move the printer over to the regular registry.
366 # Move the printer over to the regular registry.
367 printer = self.deferred_pprinters.pop(key)
367 printer = self.deferred_pprinters.pop(key)
368 self.type_pprinters[cls] = printer
368 self.type_pprinters[cls] = printer
369 return printer
369 return printer
370
370
371
371
372 class Printable(object):
372 class Printable(object):
373
373
374 def output(self, stream, output_width):
374 def output(self, stream, output_width):
375 return output_width
375 return output_width
376
376
377
377
378 class Text(Printable):
378 class Text(Printable):
379
379
380 def __init__(self):
380 def __init__(self):
381 self.objs = []
381 self.objs = []
382 self.width = 0
382 self.width = 0
383
383
384 def output(self, stream, output_width):
384 def output(self, stream, output_width):
385 for obj in self.objs:
385 for obj in self.objs:
386 stream.write(obj)
386 stream.write(obj)
387 return output_width + self.width
387 return output_width + self.width
388
388
389 def add(self, obj, width):
389 def add(self, obj, width):
390 self.objs.append(obj)
390 self.objs.append(obj)
391 self.width += width
391 self.width += width
392
392
393
393
394 class Breakable(Printable):
394 class Breakable(Printable):
395
395
396 def __init__(self, seq, width, pretty):
396 def __init__(self, seq, width, pretty):
397 self.obj = seq
397 self.obj = seq
398 self.width = width
398 self.width = width
399 self.pretty = pretty
399 self.pretty = pretty
400 self.indentation = pretty.indentation
400 self.indentation = pretty.indentation
401 self.group = pretty.group_stack[-1]
401 self.group = pretty.group_stack[-1]
402 self.group.breakables.append(self)
402 self.group.breakables.append(self)
403
403
404 def output(self, stream, output_width):
404 def output(self, stream, output_width):
405 self.group.breakables.popleft()
405 self.group.breakables.popleft()
406 if self.group.want_break:
406 if self.group.want_break:
407 stream.write(self.pretty.newline)
407 stream.write(self.pretty.newline)
408 stream.write(' ' * self.indentation)
408 stream.write(' ' * self.indentation)
409 return self.indentation
409 return self.indentation
410 if not self.group.breakables:
410 if not self.group.breakables:
411 self.pretty.group_queue.remove(self.group)
411 self.pretty.group_queue.remove(self.group)
412 stream.write(self.obj)
412 stream.write(self.obj)
413 return output_width + self.width
413 return output_width + self.width
414
414
415
415
416 class Group(Printable):
416 class Group(Printable):
417
417
418 def __init__(self, depth):
418 def __init__(self, depth):
419 self.depth = depth
419 self.depth = depth
420 self.breakables = deque()
420 self.breakables = deque()
421 self.want_break = False
421 self.want_break = False
422
422
423
423
424 class GroupQueue(object):
424 class GroupQueue(object):
425
425
426 def __init__(self, *groups):
426 def __init__(self, *groups):
427 self.queue = []
427 self.queue = []
428 for group in groups:
428 for group in groups:
429 self.enq(group)
429 self.enq(group)
430
430
431 def enq(self, group):
431 def enq(self, group):
432 depth = group.depth
432 depth = group.depth
433 while depth > len(self.queue) - 1:
433 while depth > len(self.queue) - 1:
434 self.queue.append([])
434 self.queue.append([])
435 self.queue[depth].append(group)
435 self.queue[depth].append(group)
436
436
437 def deq(self):
437 def deq(self):
438 for stack in self.queue:
438 for stack in self.queue:
439 for idx, group in enumerate(reversed(stack)):
439 for idx, group in enumerate(reversed(stack)):
440 if group.breakables:
440 if group.breakables:
441 del stack[idx]
441 del stack[idx]
442 group.want_break = True
442 group.want_break = True
443 return group
443 return group
444 for group in stack:
444 for group in stack:
445 group.want_break = True
445 group.want_break = True
446 del stack[:]
446 del stack[:]
447
447
448 def remove(self, group):
448 def remove(self, group):
449 try:
449 try:
450 self.queue[group.depth].remove(group)
450 self.queue[group.depth].remove(group)
451 except ValueError:
451 except ValueError:
452 pass
452 pass
453
453
454
454
455 _baseclass_reprs = (object.__repr__, types.InstanceType.__repr__)
455 _baseclass_reprs = (object.__repr__, types.InstanceType.__repr__)
456
456
457
457
458 def _default_pprint(obj, p, cycle):
458 def _default_pprint(obj, p, cycle):
459 """
459 """
460 The default print function. Used if an object does not provide one and
460 The default print function. Used if an object does not provide one and
461 it's none of the builtin objects.
461 it's none of the builtin objects.
462 """
462 """
463 klass = getattr(obj, '__class__', None) or type(obj)
463 klass = getattr(obj, '__class__', None) or type(obj)
464 if getattr(klass, '__repr__', None) not in _baseclass_reprs:
464 if getattr(klass, '__repr__', None) not in _baseclass_reprs:
465 # A user-provided repr.
465 # A user-provided repr.
466 p.text(repr(obj))
466 p.text(repr(obj))
467 return
467 return
468 p.begin_group(1, '<')
468 p.begin_group(1, '<')
469 p.pretty(klass)
469 p.pretty(klass)
470 p.text(' at 0x%x' % id(obj))
470 p.text(' at 0x%x' % id(obj))
471 if cycle:
471 if cycle:
472 p.text(' ...')
472 p.text(' ...')
473 elif p.verbose:
473 elif p.verbose:
474 first = True
474 first = True
475 for key in dir(obj):
475 for key in dir(obj):
476 if not key.startswith('_'):
476 if not key.startswith('_'):
477 try:
477 try:
478 value = getattr(obj, key)
478 value = getattr(obj, key)
479 except AttributeError:
479 except AttributeError:
480 continue
480 continue
481 if isinstance(value, types.MethodType):
481 if isinstance(value, types.MethodType):
482 continue
482 continue
483 if not first:
483 if not first:
484 p.text(',')
484 p.text(',')
485 p.breakable()
485 p.breakable()
486 p.text(key)
486 p.text(key)
487 p.text('=')
487 p.text('=')
488 step = len(key) + 1
488 step = len(key) + 1
489 p.indentation += step
489 p.indentation += step
490 p.pretty(value)
490 p.pretty(value)
491 p.indentation -= step
491 p.indentation -= step
492 first = False
492 first = False
493 p.end_group(1, '>')
493 p.end_group(1, '>')
494
494
495
495
496 def _seq_pprinter_factory(start, end):
496 def _seq_pprinter_factory(start, end, basetype):
497 """
497 """
498 Factory that returns a pprint function useful for sequences. Used by
498 Factory that returns a pprint function useful for sequences. Used by
499 the default pprint for tuples, dicts, lists, sets and frozensets.
499 the default pprint for tuples, dicts, lists, sets and frozensets.
500 """
500 """
501 def inner(obj, p, cycle):
501 def inner(obj, p, cycle):
502 typ = type(obj)
503 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
504 # If the subclass provides its own repr, use it instead.
505 return p.text(typ.__repr__(obj))
506
502 if cycle:
507 if cycle:
503 return p.text(start + '...' + end)
508 return p.text(start + '...' + end)
504 step = len(start)
509 step = len(start)
505 p.begin_group(step, start)
510 p.begin_group(step, start)
506 for idx, x in enumerate(obj):
511 for idx, x in enumerate(obj):
507 if idx:
512 if idx:
508 p.text(',')
513 p.text(',')
509 p.breakable()
514 p.breakable()
510 p.pretty(x)
515 p.pretty(x)
511 if len(obj) == 1 and type(obj) is tuple:
516 if len(obj) == 1 and type(obj) is tuple:
512 # Special case for 1-item tuples.
517 # Special case for 1-item tuples.
513 p.text(',')
518 p.text(',')
514 p.end_group(step, end)
519 p.end_group(step, end)
515 return inner
520 return inner
516
521
517
522
518 def _dict_pprinter_factory(start, end):
523 def _dict_pprinter_factory(start, end, basetype=None):
519 """
524 """
520 Factory that returns a pprint function used by the default pprint of
525 Factory that returns a pprint function used by the default pprint of
521 dicts and dict proxies.
526 dicts and dict proxies.
522 """
527 """
523 def inner(obj, p, cycle):
528 def inner(obj, p, cycle):
529 typ = type(obj)
530 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
531 # If the subclass provides its own repr, use it instead.
532 return p.text(typ.__repr__(obj))
533
524 if cycle:
534 if cycle:
525 return p.text('{...}')
535 return p.text('{...}')
526 p.begin_group(1, start)
536 p.begin_group(1, start)
527 keys = obj.keys()
537 keys = obj.keys()
528 try:
538 try:
529 keys.sort()
539 keys.sort()
530 except Exception, e:
540 except Exception, e:
531 # Sometimes the keys don't sort.
541 # Sometimes the keys don't sort.
532 pass
542 pass
533 for idx, key in enumerate(keys):
543 for idx, key in enumerate(keys):
534 if idx:
544 if idx:
535 p.text(',')
545 p.text(',')
536 p.breakable()
546 p.breakable()
537 p.pretty(key)
547 p.pretty(key)
538 p.text(': ')
548 p.text(': ')
539 p.pretty(obj[key])
549 p.pretty(obj[key])
540 p.end_group(1, end)
550 p.end_group(1, end)
541 return inner
551 return inner
542
552
543
553
544 def _super_pprint(obj, p, cycle):
554 def _super_pprint(obj, p, cycle):
545 """The pprint for the super type."""
555 """The pprint for the super type."""
546 p.begin_group(8, '<super: ')
556 p.begin_group(8, '<super: ')
547 p.pretty(obj.__self_class__)
557 p.pretty(obj.__self_class__)
548 p.text(',')
558 p.text(',')
549 p.breakable()
559 p.breakable()
550 p.pretty(obj.__self__)
560 p.pretty(obj.__self__)
551 p.end_group(8, '>')
561 p.end_group(8, '>')
552
562
553
563
554 def _re_pattern_pprint(obj, p, cycle):
564 def _re_pattern_pprint(obj, p, cycle):
555 """The pprint function for regular expression patterns."""
565 """The pprint function for regular expression patterns."""
556 p.text('re.compile(')
566 p.text('re.compile(')
557 pattern = repr(obj.pattern)
567 pattern = repr(obj.pattern)
558 if pattern[:1] in 'uU':
568 if pattern[:1] in 'uU':
559 pattern = pattern[1:]
569 pattern = pattern[1:]
560 prefix = 'ur'
570 prefix = 'ur'
561 else:
571 else:
562 prefix = 'r'
572 prefix = 'r'
563 pattern = prefix + pattern.replace('\\\\', '\\')
573 pattern = prefix + pattern.replace('\\\\', '\\')
564 p.text(pattern)
574 p.text(pattern)
565 if obj.flags:
575 if obj.flags:
566 p.text(',')
576 p.text(',')
567 p.breakable()
577 p.breakable()
568 done_one = False
578 done_one = False
569 for flag in ('TEMPLATE', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL',
579 for flag in ('TEMPLATE', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL',
570 'UNICODE', 'VERBOSE', 'DEBUG'):
580 'UNICODE', 'VERBOSE', 'DEBUG'):
571 if obj.flags & getattr(re, flag):
581 if obj.flags & getattr(re, flag):
572 if done_one:
582 if done_one:
573 p.text('|')
583 p.text('|')
574 p.text('re.' + flag)
584 p.text('re.' + flag)
575 done_one = True
585 done_one = True
576 p.text(')')
586 p.text(')')
577
587
578
588
579 def _type_pprint(obj, p, cycle):
589 def _type_pprint(obj, p, cycle):
580 """The pprint for classes and types."""
590 """The pprint for classes and types."""
581 if obj.__module__ in ('__builtin__', 'exceptions'):
591 if obj.__module__ in ('__builtin__', 'exceptions'):
582 name = obj.__name__
592 name = obj.__name__
583 else:
593 else:
584 name = obj.__module__ + '.' + obj.__name__
594 name = obj.__module__ + '.' + obj.__name__
585 p.text(name)
595 p.text(name)
586
596
587
597
588 def _repr_pprint(obj, p, cycle):
598 def _repr_pprint(obj, p, cycle):
589 """A pprint that just redirects to the normal repr function."""
599 """A pprint that just redirects to the normal repr function."""
590 p.text(repr(obj))
600 p.text(repr(obj))
591
601
592
602
593 def _function_pprint(obj, p, cycle):
603 def _function_pprint(obj, p, cycle):
594 """Base pprint for all functions and builtin functions."""
604 """Base pprint for all functions and builtin functions."""
595 if obj.__module__ in ('__builtin__', 'exceptions') or not obj.__module__:
605 if obj.__module__ in ('__builtin__', 'exceptions') or not obj.__module__:
596 name = obj.__name__
606 name = obj.__name__
597 else:
607 else:
598 name = obj.__module__ + '.' + obj.__name__
608 name = obj.__module__ + '.' + obj.__name__
599 p.text('<function %s>' % name)
609 p.text('<function %s>' % name)
600
610
601
611
602 def _exception_pprint(obj, p, cycle):
612 def _exception_pprint(obj, p, cycle):
603 """Base pprint for all exceptions."""
613 """Base pprint for all exceptions."""
604 if obj.__class__.__module__ == 'exceptions':
614 if obj.__class__.__module__ == 'exceptions':
605 name = obj.__class__.__name__
615 name = obj.__class__.__name__
606 else:
616 else:
607 name = '%s.%s' % (
617 name = '%s.%s' % (
608 obj.__class__.__module__,
618 obj.__class__.__module__,
609 obj.__class__.__name__
619 obj.__class__.__name__
610 )
620 )
611 step = len(name) + 1
621 step = len(name) + 1
612 p.begin_group(step, '(')
622 p.begin_group(step, '(')
613 for idx, arg in enumerate(getattr(obj, 'args', ())):
623 for idx, arg in enumerate(getattr(obj, 'args', ())):
614 if idx:
624 if idx:
615 p.text(',')
625 p.text(',')
616 p.breakable()
626 p.breakable()
617 p.pretty(arg)
627 p.pretty(arg)
618 p.end_group(step, ')')
628 p.end_group(step, ')')
619
629
620
630
621 #: the exception base
631 #: the exception base
622 try:
632 try:
623 _exception_base = BaseException
633 _exception_base = BaseException
624 except NameError:
634 except NameError:
625 _exception_base = Exception
635 _exception_base = Exception
626
636
627
637
628 #: printers for builtin types
638 #: printers for builtin types
629 _type_pprinters = {
639 _type_pprinters = {
630 int: _repr_pprint,
640 int: _repr_pprint,
631 long: _repr_pprint,
641 long: _repr_pprint,
632 float: _repr_pprint,
642 float: _repr_pprint,
633 str: _repr_pprint,
643 str: _repr_pprint,
634 unicode: _repr_pprint,
644 unicode: _repr_pprint,
635 tuple: _seq_pprinter_factory('(', ')'),
645 tuple: _seq_pprinter_factory('(', ')', tuple),
636 list: _seq_pprinter_factory('[', ']'),
646 list: _seq_pprinter_factory('[', ']', list),
637 dict: _dict_pprinter_factory('{', '}'),
647 dict: _dict_pprinter_factory('{', '}', dict),
638 types.DictProxyType: _dict_pprinter_factory('<dictproxy {', '}>'),
648 types.DictProxyType: _dict_pprinter_factory('<dictproxy {', '}>'),
639 set: _seq_pprinter_factory('set([', '])'),
649 set: _seq_pprinter_factory('set([', '])', set),
640 frozenset: _seq_pprinter_factory('frozenset([', '])'),
650 frozenset: _seq_pprinter_factory('frozenset([', '])', frozenset),
641 super: _super_pprint,
651 super: _super_pprint,
642 _re_pattern_type: _re_pattern_pprint,
652 _re_pattern_type: _re_pattern_pprint,
643 type: _type_pprint,
653 type: _type_pprint,
644 types.ClassType: _type_pprint,
654 types.ClassType: _type_pprint,
645 types.FunctionType: _function_pprint,
655 types.FunctionType: _function_pprint,
646 types.BuiltinFunctionType: _function_pprint,
656 types.BuiltinFunctionType: _function_pprint,
647 types.SliceType: _repr_pprint,
657 types.SliceType: _repr_pprint,
648 types.MethodType: _repr_pprint,
658 types.MethodType: _repr_pprint,
649 xrange: _repr_pprint,
659 xrange: _repr_pprint,
650 datetime.datetime: _repr_pprint,
660 datetime.datetime: _repr_pprint,
651 datetime.timedelta: _repr_pprint,
661 datetime.timedelta: _repr_pprint,
652 _exception_base: _exception_pprint
662 _exception_base: _exception_pprint
653 }
663 }
654
664
655 #: printers for types specified by name
665 #: printers for types specified by name
656 _deferred_type_pprinters = {
666 _deferred_type_pprinters = {
657 }
667 }
658
668
659 def for_type(typ, func):
669 def for_type(typ, func):
660 """
670 """
661 Add a pretty printer for a given type.
671 Add a pretty printer for a given type.
662 """
672 """
663 oldfunc = _type_pprinters.get(typ, None)
673 oldfunc = _type_pprinters.get(typ, None)
664 if func is not None:
674 if func is not None:
665 # To support easy restoration of old pprinters, we need to ignore Nones.
675 # To support easy restoration of old pprinters, we need to ignore Nones.
666 _type_pprinters[typ] = func
676 _type_pprinters[typ] = func
667 return oldfunc
677 return oldfunc
668
678
669 def for_type_by_name(type_module, type_name, func):
679 def for_type_by_name(type_module, type_name, func):
670 """
680 """
671 Add a pretty printer for a type specified by the module and name of a type
681 Add a pretty printer for a type specified by the module and name of a type
672 rather than the type object itself.
682 rather than the type object itself.
673 """
683 """
674 key = (type_module, type_name)
684 key = (type_module, type_name)
675 oldfunc = _deferred_type_pprinters.get(key, None)
685 oldfunc = _deferred_type_pprinters.get(key, None)
676 if func is not None:
686 if func is not None:
677 # To support easy restoration of old pprinters, we need to ignore Nones.
687 # To support easy restoration of old pprinters, we need to ignore Nones.
678 _deferred_type_pprinters[key] = func
688 _deferred_type_pprinters[key] = func
679 return oldfunc
689 return oldfunc
680
690
681
691
682 #: printers for the default singletons
692 #: printers for the default singletons
683 _singleton_pprinters = dict.fromkeys(map(id, [None, True, False, Ellipsis,
693 _singleton_pprinters = dict.fromkeys(map(id, [None, True, False, Ellipsis,
684 NotImplemented]), _repr_pprint)
694 NotImplemented]), _repr_pprint)
685
695
686
696
687 if __name__ == '__main__':
697 if __name__ == '__main__':
688 from random import randrange
698 from random import randrange
689 class Foo(object):
699 class Foo(object):
690 def __init__(self):
700 def __init__(self):
691 self.foo = 1
701 self.foo = 1
692 self.bar = re.compile(r'\s+')
702 self.bar = re.compile(r'\s+')
693 self.blub = dict.fromkeys(range(30), randrange(1, 40))
703 self.blub = dict.fromkeys(range(30), randrange(1, 40))
694 self.hehe = 23424.234234
704 self.hehe = 23424.234234
695 self.list = ["blub", "blah", self]
705 self.list = ["blub", "blah", self]
696
706
697 def get_foo(self):
707 def get_foo(self):
698 print "foo"
708 print "foo"
699
709
700 pprint(Foo(), verbose=True)
710 pprint(Foo(), verbose=True)
General Comments 0
You need to be logged in to leave comments. Login now