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