##// END OF EJS Templates
Python 3 compatibility in IPython.lib.pretty
Thomas Kluyver -
Show More
@@ -1,713 +1,725 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 `_repr_pretty_` method to your object and call the methods on the
32 add a `_repr_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 _repr_pretty_(self, p, cycle):
37 def _repr_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 `_repr_pretty_` method for a list
45 Here the example implementation of a `_repr_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 _repr_pretty_(self, p, cycle):
51 def _repr_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 _repr_pretty_(self, p, cycle):
78 def _repr_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 `_repr_pretty_`
167 this printer knows nothing about the default pprinters or the `_repr_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 # First try to find registered singleton printers for the type.
333 # First try to find registered singleton printers for the type.
334 try:
334 try:
335 printer = self.singleton_pprinters[obj_id]
335 printer = self.singleton_pprinters[obj_id]
336 except (TypeError, KeyError):
336 except (TypeError, KeyError):
337 pass
337 pass
338 else:
338 else:
339 return printer(obj, self, cycle)
339 return printer(obj, self, cycle)
340 # Next look for type_printers.
340 # Next look for type_printers.
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 # Finally look for special method names.
348 # Finally look for special method names.
349 if hasattr(obj_class, '_repr_pretty_'):
349 if hasattr(obj_class, '_repr_pretty_'):
350 return obj_class._repr_pretty_(obj, self, cycle)
350 return obj_class._repr_pretty_(obj, self, cycle)
351 return _default_pprint(obj, self, cycle)
351 return _default_pprint(obj, self, cycle)
352 finally:
352 finally:
353 self.end_group()
353 self.end_group()
354 self.stack.pop()
354 self.stack.pop()
355
355
356 def _in_deferred_types(self, cls):
356 def _in_deferred_types(self, cls):
357 """
357 """
358 Check if the given class is specified in the deferred type registry.
358 Check if the given class is specified in the deferred type registry.
359
359
360 Returns the printer from the registry if it exists, and None if the
360 Returns the printer from the registry if it exists, and None if the
361 class is not in the registry. Successful matches will be moved to the
361 class is not in the registry. Successful matches will be moved to the
362 regular type registry for future use.
362 regular type registry for future use.
363 """
363 """
364 mod = getattr(cls, '__module__', None)
364 mod = getattr(cls, '__module__', None)
365 name = getattr(cls, '__name__', None)
365 name = getattr(cls, '__name__', None)
366 key = (mod, name)
366 key = (mod, name)
367 printer = None
367 printer = None
368 if key in self.deferred_pprinters:
368 if key in self.deferred_pprinters:
369 # Move the printer over to the regular registry.
369 # Move the printer over to the regular registry.
370 printer = self.deferred_pprinters.pop(key)
370 printer = self.deferred_pprinters.pop(key)
371 self.type_pprinters[cls] = printer
371 self.type_pprinters[cls] = printer
372 return printer
372 return printer
373
373
374
374
375 class Printable(object):
375 class Printable(object):
376
376
377 def output(self, stream, output_width):
377 def output(self, stream, output_width):
378 return output_width
378 return output_width
379
379
380
380
381 class Text(Printable):
381 class Text(Printable):
382
382
383 def __init__(self):
383 def __init__(self):
384 self.objs = []
384 self.objs = []
385 self.width = 0
385 self.width = 0
386
386
387 def output(self, stream, output_width):
387 def output(self, stream, output_width):
388 for obj in self.objs:
388 for obj in self.objs:
389 stream.write(obj)
389 stream.write(obj)
390 return output_width + self.width
390 return output_width + self.width
391
391
392 def add(self, obj, width):
392 def add(self, obj, width):
393 self.objs.append(obj)
393 self.objs.append(obj)
394 self.width += width
394 self.width += width
395
395
396
396
397 class Breakable(Printable):
397 class Breakable(Printable):
398
398
399 def __init__(self, seq, width, pretty):
399 def __init__(self, seq, width, pretty):
400 self.obj = seq
400 self.obj = seq
401 self.width = width
401 self.width = width
402 self.pretty = pretty
402 self.pretty = pretty
403 self.indentation = pretty.indentation
403 self.indentation = pretty.indentation
404 self.group = pretty.group_stack[-1]
404 self.group = pretty.group_stack[-1]
405 self.group.breakables.append(self)
405 self.group.breakables.append(self)
406
406
407 def output(self, stream, output_width):
407 def output(self, stream, output_width):
408 self.group.breakables.popleft()
408 self.group.breakables.popleft()
409 if self.group.want_break:
409 if self.group.want_break:
410 stream.write(self.pretty.newline)
410 stream.write(self.pretty.newline)
411 stream.write(' ' * self.indentation)
411 stream.write(' ' * self.indentation)
412 return self.indentation
412 return self.indentation
413 if not self.group.breakables:
413 if not self.group.breakables:
414 self.pretty.group_queue.remove(self.group)
414 self.pretty.group_queue.remove(self.group)
415 stream.write(self.obj)
415 stream.write(self.obj)
416 return output_width + self.width
416 return output_width + self.width
417
417
418
418
419 class Group(Printable):
419 class Group(Printable):
420
420
421 def __init__(self, depth):
421 def __init__(self, depth):
422 self.depth = depth
422 self.depth = depth
423 self.breakables = deque()
423 self.breakables = deque()
424 self.want_break = False
424 self.want_break = False
425
425
426
426
427 class GroupQueue(object):
427 class GroupQueue(object):
428
428
429 def __init__(self, *groups):
429 def __init__(self, *groups):
430 self.queue = []
430 self.queue = []
431 for group in groups:
431 for group in groups:
432 self.enq(group)
432 self.enq(group)
433
433
434 def enq(self, group):
434 def enq(self, group):
435 depth = group.depth
435 depth = group.depth
436 while depth > len(self.queue) - 1:
436 while depth > len(self.queue) - 1:
437 self.queue.append([])
437 self.queue.append([])
438 self.queue[depth].append(group)
438 self.queue[depth].append(group)
439
439
440 def deq(self):
440 def deq(self):
441 for stack in self.queue:
441 for stack in self.queue:
442 for idx, group in enumerate(reversed(stack)):
442 for idx, group in enumerate(reversed(stack)):
443 if group.breakables:
443 if group.breakables:
444 del stack[idx]
444 del stack[idx]
445 group.want_break = True
445 group.want_break = True
446 return group
446 return group
447 for group in stack:
447 for group in stack:
448 group.want_break = True
448 group.want_break = True
449 del stack[:]
449 del stack[:]
450
450
451 def remove(self, group):
451 def remove(self, group):
452 try:
452 try:
453 self.queue[group.depth].remove(group)
453 self.queue[group.depth].remove(group)
454 except ValueError:
454 except ValueError:
455 pass
455 pass
456
456
457
457 try:
458 _baseclass_reprs = (object.__repr__, types.InstanceType.__repr__)
458 _baseclass_reprs = (object.__repr__, types.InstanceType.__repr__)
459 except AttributeError: # Python 3
460 _baseclass_reprs = (object.__repr__,)
459
461
460
462
461 def _default_pprint(obj, p, cycle):
463 def _default_pprint(obj, p, cycle):
462 """
464 """
463 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
464 it's none of the builtin objects.
466 it's none of the builtin objects.
465 """
467 """
466 klass = getattr(obj, '__class__', None) or type(obj)
468 klass = getattr(obj, '__class__', None) or type(obj)
467 if getattr(klass, '__repr__', None) not in _baseclass_reprs:
469 if getattr(klass, '__repr__', None) not in _baseclass_reprs:
468 # A user-provided repr.
470 # A user-provided repr.
469 p.text(repr(obj))
471 p.text(repr(obj))
470 return
472 return
471 p.begin_group(1, '<')
473 p.begin_group(1, '<')
472 p.pretty(klass)
474 p.pretty(klass)
473 p.text(' at 0x%x' % id(obj))
475 p.text(' at 0x%x' % id(obj))
474 if cycle:
476 if cycle:
475 p.text(' ...')
477 p.text(' ...')
476 elif p.verbose:
478 elif p.verbose:
477 first = True
479 first = True
478 for key in dir(obj):
480 for key in dir(obj):
479 if not key.startswith('_'):
481 if not key.startswith('_'):
480 try:
482 try:
481 value = getattr(obj, key)
483 value = getattr(obj, key)
482 except AttributeError:
484 except AttributeError:
483 continue
485 continue
484 if isinstance(value, types.MethodType):
486 if isinstance(value, types.MethodType):
485 continue
487 continue
486 if not first:
488 if not first:
487 p.text(',')
489 p.text(',')
488 p.breakable()
490 p.breakable()
489 p.text(key)
491 p.text(key)
490 p.text('=')
492 p.text('=')
491 step = len(key) + 1
493 step = len(key) + 1
492 p.indentation += step
494 p.indentation += step
493 p.pretty(value)
495 p.pretty(value)
494 p.indentation -= step
496 p.indentation -= step
495 first = False
497 first = False
496 p.end_group(1, '>')
498 p.end_group(1, '>')
497
499
498
500
499 def _seq_pprinter_factory(start, end, basetype):
501 def _seq_pprinter_factory(start, end, basetype):
500 """
502 """
501 Factory that returns a pprint function useful for sequences. Used by
503 Factory that returns a pprint function useful for sequences. Used by
502 the default pprint for tuples, dicts, lists, sets and frozensets.
504 the default pprint for tuples, dicts, lists, sets and frozensets.
503 """
505 """
504 def inner(obj, p, cycle):
506 def inner(obj, p, cycle):
505 typ = type(obj)
507 typ = type(obj)
506 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
508 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
507 # If the subclass provides its own repr, use it instead.
509 # If the subclass provides its own repr, use it instead.
508 return p.text(typ.__repr__(obj))
510 return p.text(typ.__repr__(obj))
509
511
510 if cycle:
512 if cycle:
511 return p.text(start + '...' + end)
513 return p.text(start + '...' + end)
512 step = len(start)
514 step = len(start)
513 p.begin_group(step, start)
515 p.begin_group(step, start)
514 for idx, x in enumerate(obj):
516 for idx, x in enumerate(obj):
515 if idx:
517 if idx:
516 p.text(',')
518 p.text(',')
517 p.breakable()
519 p.breakable()
518 p.pretty(x)
520 p.pretty(x)
519 if len(obj) == 1 and type(obj) is tuple:
521 if len(obj) == 1 and type(obj) is tuple:
520 # Special case for 1-item tuples.
522 # Special case for 1-item tuples.
521 p.text(',')
523 p.text(',')
522 p.end_group(step, end)
524 p.end_group(step, end)
523 return inner
525 return inner
524
526
525
527
526 def _dict_pprinter_factory(start, end, basetype=None):
528 def _dict_pprinter_factory(start, end, basetype=None):
527 """
529 """
528 Factory that returns a pprint function used by the default pprint of
530 Factory that returns a pprint function used by the default pprint of
529 dicts and dict proxies.
531 dicts and dict proxies.
530 """
532 """
531 def inner(obj, p, cycle):
533 def inner(obj, p, cycle):
532 typ = type(obj)
534 typ = type(obj)
533 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
535 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
534 # If the subclass provides its own repr, use it instead.
536 # If the subclass provides its own repr, use it instead.
535 return p.text(typ.__repr__(obj))
537 return p.text(typ.__repr__(obj))
536
538
537 if cycle:
539 if cycle:
538 return p.text('{...}')
540 return p.text('{...}')
539 p.begin_group(1, start)
541 p.begin_group(1, start)
540 keys = obj.keys()
542 keys = obj.keys()
541 try:
543 try:
542 keys.sort()
544 keys.sort()
543 except Exception, e:
545 except Exception, e:
544 # Sometimes the keys don't sort.
546 # Sometimes the keys don't sort.
545 pass
547 pass
546 for idx, key in enumerate(keys):
548 for idx, key in enumerate(keys):
547 if idx:
549 if idx:
548 p.text(',')
550 p.text(',')
549 p.breakable()
551 p.breakable()
550 p.pretty(key)
552 p.pretty(key)
551 p.text(': ')
553 p.text(': ')
552 p.pretty(obj[key])
554 p.pretty(obj[key])
553 p.end_group(1, end)
555 p.end_group(1, end)
554 return inner
556 return inner
555
557
556
558
557 def _super_pprint(obj, p, cycle):
559 def _super_pprint(obj, p, cycle):
558 """The pprint for the super type."""
560 """The pprint for the super type."""
559 p.begin_group(8, '<super: ')
561 p.begin_group(8, '<super: ')
560 p.pretty(obj.__self_class__)
562 p.pretty(obj.__self_class__)
561 p.text(',')
563 p.text(',')
562 p.breakable()
564 p.breakable()
563 p.pretty(obj.__self__)
565 p.pretty(obj.__self__)
564 p.end_group(8, '>')
566 p.end_group(8, '>')
565
567
566
568
567 def _re_pattern_pprint(obj, p, cycle):
569 def _re_pattern_pprint(obj, p, cycle):
568 """The pprint function for regular expression patterns."""
570 """The pprint function for regular expression patterns."""
569 p.text('re.compile(')
571 p.text('re.compile(')
570 pattern = repr(obj.pattern)
572 pattern = repr(obj.pattern)
571 if pattern[:1] in 'uU':
573 if pattern[:1] in 'uU':
572 pattern = pattern[1:]
574 pattern = pattern[1:]
573 prefix = 'ur'
575 prefix = 'ur'
574 else:
576 else:
575 prefix = 'r'
577 prefix = 'r'
576 pattern = prefix + pattern.replace('\\\\', '\\')
578 pattern = prefix + pattern.replace('\\\\', '\\')
577 p.text(pattern)
579 p.text(pattern)
578 if obj.flags:
580 if obj.flags:
579 p.text(',')
581 p.text(',')
580 p.breakable()
582 p.breakable()
581 done_one = False
583 done_one = False
582 for flag in ('TEMPLATE', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL',
584 for flag in ('TEMPLATE', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL',
583 'UNICODE', 'VERBOSE', 'DEBUG'):
585 'UNICODE', 'VERBOSE', 'DEBUG'):
584 if obj.flags & getattr(re, flag):
586 if obj.flags & getattr(re, flag):
585 if done_one:
587 if done_one:
586 p.text('|')
588 p.text('|')
587 p.text('re.' + flag)
589 p.text('re.' + flag)
588 done_one = True
590 done_one = True
589 p.text(')')
591 p.text(')')
590
592
591
593
592 def _type_pprint(obj, p, cycle):
594 def _type_pprint(obj, p, cycle):
593 """The pprint for classes and types."""
595 """The pprint for classes and types."""
594 if obj.__module__ in ('__builtin__', 'exceptions'):
596 if obj.__module__ in ('__builtin__', 'exceptions'):
595 name = obj.__name__
597 name = obj.__name__
596 else:
598 else:
597 name = obj.__module__ + '.' + obj.__name__
599 name = obj.__module__ + '.' + obj.__name__
598 p.text(name)
600 p.text(name)
599
601
600
602
601 def _repr_pprint(obj, p, cycle):
603 def _repr_pprint(obj, p, cycle):
602 """A pprint that just redirects to the normal repr function."""
604 """A pprint that just redirects to the normal repr function."""
603 p.text(repr(obj))
605 p.text(repr(obj))
604
606
605
607
606 def _function_pprint(obj, p, cycle):
608 def _function_pprint(obj, p, cycle):
607 """Base pprint for all functions and builtin functions."""
609 """Base pprint for all functions and builtin functions."""
608 if obj.__module__ in ('__builtin__', 'exceptions') or not obj.__module__:
610 if obj.__module__ in ('__builtin__', 'exceptions') or not obj.__module__:
609 name = obj.__name__
611 name = obj.__name__
610 else:
612 else:
611 name = obj.__module__ + '.' + obj.__name__
613 name = obj.__module__ + '.' + obj.__name__
612 p.text('<function %s>' % name)
614 p.text('<function %s>' % name)
613
615
614
616
615 def _exception_pprint(obj, p, cycle):
617 def _exception_pprint(obj, p, cycle):
616 """Base pprint for all exceptions."""
618 """Base pprint for all exceptions."""
617 if obj.__class__.__module__ == 'exceptions':
619 if obj.__class__.__module__ == 'exceptions':
618 name = obj.__class__.__name__
620 name = obj.__class__.__name__
619 else:
621 else:
620 name = '%s.%s' % (
622 name = '%s.%s' % (
621 obj.__class__.__module__,
623 obj.__class__.__module__,
622 obj.__class__.__name__
624 obj.__class__.__name__
623 )
625 )
624 step = len(name) + 1
626 step = len(name) + 1
625 p.begin_group(step, '(')
627 p.begin_group(step, '(')
626 for idx, arg in enumerate(getattr(obj, 'args', ())):
628 for idx, arg in enumerate(getattr(obj, 'args', ())):
627 if idx:
629 if idx:
628 p.text(',')
630 p.text(',')
629 p.breakable()
631 p.breakable()
630 p.pretty(arg)
632 p.pretty(arg)
631 p.end_group(step, ')')
633 p.end_group(step, ')')
632
634
633
635
634 #: the exception base
636 #: the exception base
635 try:
637 try:
636 _exception_base = BaseException
638 _exception_base = BaseException
637 except NameError:
639 except NameError:
638 _exception_base = Exception
640 _exception_base = Exception
639
641
640
642
641 #: printers for builtin types
643 #: printers for builtin types
642 _type_pprinters = {
644 _type_pprinters = {
643 int: _repr_pprint,
645 int: _repr_pprint,
644 long: _repr_pprint,
646 long: _repr_pprint,
645 float: _repr_pprint,
647 float: _repr_pprint,
646 str: _repr_pprint,
648 str: _repr_pprint,
647 unicode: _repr_pprint,
649 unicode: _repr_pprint,
648 tuple: _seq_pprinter_factory('(', ')', tuple),
650 tuple: _seq_pprinter_factory('(', ')', tuple),
649 list: _seq_pprinter_factory('[', ']', list),
651 list: _seq_pprinter_factory('[', ']', list),
650 dict: _dict_pprinter_factory('{', '}', dict),
652 dict: _dict_pprinter_factory('{', '}', dict),
651 types.DictProxyType: _dict_pprinter_factory('<dictproxy {', '}>'),
653
652 set: _seq_pprinter_factory('set([', '])', set),
654 set: _seq_pprinter_factory('set([', '])', set),
653 frozenset: _seq_pprinter_factory('frozenset([', '])', frozenset),
655 frozenset: _seq_pprinter_factory('frozenset([', '])', frozenset),
654 super: _super_pprint,
656 super: _super_pprint,
655 _re_pattern_type: _re_pattern_pprint,
657 _re_pattern_type: _re_pattern_pprint,
656 type: _type_pprint,
658 type: _type_pprint,
657 types.ClassType: _type_pprint,
658 types.FunctionType: _function_pprint,
659 types.FunctionType: _function_pprint,
659 types.BuiltinFunctionType: _function_pprint,
660 types.BuiltinFunctionType: _function_pprint,
660 types.SliceType: _repr_pprint,
661 types.SliceType: _repr_pprint,
661 types.MethodType: _repr_pprint,
662 types.MethodType: _repr_pprint,
662 xrange: _repr_pprint,
663
663 datetime.datetime: _repr_pprint,
664 datetime.datetime: _repr_pprint,
664 datetime.timedelta: _repr_pprint,
665 datetime.timedelta: _repr_pprint,
665 _exception_base: _exception_pprint
666 _exception_base: _exception_pprint
666 }
667 }
667
668
669 try:
670 _type_pprinters[types.DictProxyType] = _dict_pprinter_factory('<dictproxy {', '}>')
671 _type_pprinters[types.ClassType] = _type_pprint,
672 except AttributeError: # Python 3
673 pass
674
675 try:
676 _type_pprinters[xrange] = _repr_pprint
677 except NameError:
678 _type_pprinters[range] = _repr_pprint
679
668 #: printers for types specified by name
680 #: printers for types specified by name
669 _deferred_type_pprinters = {
681 _deferred_type_pprinters = {
670 }
682 }
671
683
672 def for_type(typ, func):
684 def for_type(typ, func):
673 """
685 """
674 Add a pretty printer for a given type.
686 Add a pretty printer for a given type.
675 """
687 """
676 oldfunc = _type_pprinters.get(typ, None)
688 oldfunc = _type_pprinters.get(typ, None)
677 if func is not None:
689 if func is not None:
678 # To support easy restoration of old pprinters, we need to ignore Nones.
690 # To support easy restoration of old pprinters, we need to ignore Nones.
679 _type_pprinters[typ] = func
691 _type_pprinters[typ] = func
680 return oldfunc
692 return oldfunc
681
693
682 def for_type_by_name(type_module, type_name, func):
694 def for_type_by_name(type_module, type_name, func):
683 """
695 """
684 Add a pretty printer for a type specified by the module and name of a type
696 Add a pretty printer for a type specified by the module and name of a type
685 rather than the type object itself.
697 rather than the type object itself.
686 """
698 """
687 key = (type_module, type_name)
699 key = (type_module, type_name)
688 oldfunc = _deferred_type_pprinters.get(key, None)
700 oldfunc = _deferred_type_pprinters.get(key, None)
689 if func is not None:
701 if func is not None:
690 # To support easy restoration of old pprinters, we need to ignore Nones.
702 # To support easy restoration of old pprinters, we need to ignore Nones.
691 _deferred_type_pprinters[key] = func
703 _deferred_type_pprinters[key] = func
692 return oldfunc
704 return oldfunc
693
705
694
706
695 #: printers for the default singletons
707 #: printers for the default singletons
696 _singleton_pprinters = dict.fromkeys(map(id, [None, True, False, Ellipsis,
708 _singleton_pprinters = dict.fromkeys(map(id, [None, True, False, Ellipsis,
697 NotImplemented]), _repr_pprint)
709 NotImplemented]), _repr_pprint)
698
710
699
711
700 if __name__ == '__main__':
712 if __name__ == '__main__':
701 from random import randrange
713 from random import randrange
702 class Foo(object):
714 class Foo(object):
703 def __init__(self):
715 def __init__(self):
704 self.foo = 1
716 self.foo = 1
705 self.bar = re.compile(r'\s+')
717 self.bar = re.compile(r'\s+')
706 self.blub = dict.fromkeys(range(30), randrange(1, 40))
718 self.blub = dict.fromkeys(range(30), randrange(1, 40))
707 self.hehe = 23424.234234
719 self.hehe = 23424.234234
708 self.list = ["blub", "blah", self]
720 self.list = ["blub", "blah", self]
709
721
710 def get_foo(self):
722 def get_foo(self):
711 print "foo"
723 print "foo"
712
724
713 pprint(Foo(), verbose=True)
725 pprint(Foo(), verbose=True)
General Comments 0
You need to be logged in to leave comments. Login now