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