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