##// END OF EJS Templates
Backport PR #10767: Sort on string representation if sorting fails
Matthias Bussonnier -
Show More
@@ -1,868 +1,876
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 Here is an example implementation of a `_repr_pretty_` method for a list
37 Here is an example implementation of a `_repr_pretty_` method for a list
38 subclass::
38 subclass::
39
39
40 class MyList(list):
40 class MyList(list):
41
41
42 def _repr_pretty_(self, p, cycle):
42 def _repr_pretty_(self, p, cycle):
43 if cycle:
43 if cycle:
44 p.text('MyList(...)')
44 p.text('MyList(...)')
45 else:
45 else:
46 with p.group(8, 'MyList([', '])'):
46 with p.group(8, 'MyList([', '])'):
47 for idx, item in enumerate(self):
47 for idx, item in enumerate(self):
48 if idx:
48 if idx:
49 p.text(',')
49 p.text(',')
50 p.breakable()
50 p.breakable()
51 p.pretty(item)
51 p.pretty(item)
52
52
53 The `cycle` parameter is `True` if pretty detected a cycle. You *have* to
53 The `cycle` parameter is `True` if pretty detected a cycle. You *have* to
54 react to that or the result is an infinite loop. `p.text()` just adds
54 react to that or the result is an infinite loop. `p.text()` just adds
55 non breaking text to the output, `p.breakable()` either adds a whitespace
55 non breaking text to the output, `p.breakable()` either adds a whitespace
56 or breaks here. If you pass it an argument it's used instead of the
56 or breaks here. If you pass it an argument it's used instead of the
57 default space. `p.pretty` prettyprints another object using the pretty print
57 default space. `p.pretty` prettyprints another object using the pretty print
58 method.
58 method.
59
59
60 The first parameter to the `group` function specifies the extra indentation
60 The first parameter to the `group` function specifies the extra indentation
61 of the next line. In this example the next item will either be on the same
61 of the next line. In this example the next item will either be on the same
62 line (if the items are short enough) or aligned with the right edge of the
62 line (if the items are short enough) or aligned with the right edge of the
63 opening bracket of `MyList`.
63 opening bracket of `MyList`.
64
64
65 If you just want to indent something you can use the group function
65 If you just want to indent something you can use the group function
66 without open / close parameters. You can also use this code::
66 without open / close parameters. You can also use this code::
67
67
68 with p.indent(2):
68 with p.indent(2):
69 ...
69 ...
70
70
71 Inheritance diagram:
71 Inheritance diagram:
72
72
73 .. inheritance-diagram:: IPython.lib.pretty
73 .. inheritance-diagram:: IPython.lib.pretty
74 :parts: 3
74 :parts: 3
75
75
76 :copyright: 2007 by Armin Ronacher.
76 :copyright: 2007 by Armin Ronacher.
77 Portions (c) 2009 by Robert Kern.
77 Portions (c) 2009 by Robert Kern.
78 :license: BSD License.
78 :license: BSD License.
79 """
79 """
80 from __future__ import print_function
80 from __future__ import print_function
81 from contextlib import contextmanager
81 from contextlib import contextmanager
82 import sys
82 import sys
83 import types
83 import types
84 import re
84 import re
85 import datetime
85 import datetime
86 from collections import deque
86 from collections import deque
87
87
88 from IPython.utils.py3compat import PY3, PYPY, cast_unicode, string_types
88 from IPython.utils.py3compat import PY3, PYPY, cast_unicode, string_types
89 from IPython.utils.encoding import get_stream_enc
89 from IPython.utils.encoding import get_stream_enc
90
90
91 from io import StringIO
91 from io import StringIO
92
92
93
93
94 __all__ = ['pretty', 'pprint', 'PrettyPrinter', 'RepresentationPrinter',
94 __all__ = ['pretty', 'pprint', 'PrettyPrinter', 'RepresentationPrinter',
95 'for_type', 'for_type_by_name']
95 'for_type', 'for_type_by_name']
96
96
97
97
98 MAX_SEQ_LENGTH = 1000
98 MAX_SEQ_LENGTH = 1000
99 _re_pattern_type = type(re.compile(''))
99 _re_pattern_type = type(re.compile(''))
100
100
101 def _safe_getattr(obj, attr, default=None):
101 def _safe_getattr(obj, attr, default=None):
102 """Safe version of getattr.
102 """Safe version of getattr.
103
103
104 Same as getattr, but will return ``default`` on any Exception,
104 Same as getattr, but will return ``default`` on any Exception,
105 rather than raising.
105 rather than raising.
106 """
106 """
107 try:
107 try:
108 return getattr(obj, attr, default)
108 return getattr(obj, attr, default)
109 except Exception:
109 except Exception:
110 return default
110 return default
111
111
112 if PY3:
112 if PY3:
113 CUnicodeIO = StringIO
113 CUnicodeIO = StringIO
114 else:
114 else:
115 class CUnicodeIO(StringIO):
115 class CUnicodeIO(StringIO):
116 """StringIO that casts str to unicode on Python 2"""
116 """StringIO that casts str to unicode on Python 2"""
117 def write(self, text):
117 def write(self, text):
118 return super(CUnicodeIO, self).write(
118 return super(CUnicodeIO, self).write(
119 cast_unicode(text, encoding=get_stream_enc(sys.stdout)))
119 cast_unicode(text, encoding=get_stream_enc(sys.stdout)))
120
120
121
121
122 def _sorted_for_pprint(items):
123 """
124 Sort the given items for pretty printing. Since some predictable
125 sorting is better than no sorting at all, we sort on the string
126 representation if normal sorting fails.
127 """
128 items = list(items)
129 try:
130 return sorted(items)
131 except Exception:
132 try:
133 return sorted(items, key=str)
134 except Exception:
135 return items
136
122 def pretty(obj, verbose=False, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH):
137 def pretty(obj, verbose=False, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH):
123 """
138 """
124 Pretty print the object's representation.
139 Pretty print the object's representation.
125 """
140 """
126 stream = CUnicodeIO()
141 stream = CUnicodeIO()
127 printer = RepresentationPrinter(stream, verbose, max_width, newline, max_seq_length=max_seq_length)
142 printer = RepresentationPrinter(stream, verbose, max_width, newline, max_seq_length=max_seq_length)
128 printer.pretty(obj)
143 printer.pretty(obj)
129 printer.flush()
144 printer.flush()
130 return stream.getvalue()
145 return stream.getvalue()
131
146
132
147
133 def pprint(obj, verbose=False, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH):
148 def pprint(obj, verbose=False, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH):
134 """
149 """
135 Like `pretty` but print to stdout.
150 Like `pretty` but print to stdout.
136 """
151 """
137 printer = RepresentationPrinter(sys.stdout, verbose, max_width, newline, max_seq_length=max_seq_length)
152 printer = RepresentationPrinter(sys.stdout, verbose, max_width, newline, max_seq_length=max_seq_length)
138 printer.pretty(obj)
153 printer.pretty(obj)
139 printer.flush()
154 printer.flush()
140 sys.stdout.write(newline)
155 sys.stdout.write(newline)
141 sys.stdout.flush()
156 sys.stdout.flush()
142
157
143 class _PrettyPrinterBase(object):
158 class _PrettyPrinterBase(object):
144
159
145 @contextmanager
160 @contextmanager
146 def indent(self, indent):
161 def indent(self, indent):
147 """with statement support for indenting/dedenting."""
162 """with statement support for indenting/dedenting."""
148 self.indentation += indent
163 self.indentation += indent
149 try:
164 try:
150 yield
165 yield
151 finally:
166 finally:
152 self.indentation -= indent
167 self.indentation -= indent
153
168
154 @contextmanager
169 @contextmanager
155 def group(self, indent=0, open='', close=''):
170 def group(self, indent=0, open='', close=''):
156 """like begin_group / end_group but for the with statement."""
171 """like begin_group / end_group but for the with statement."""
157 self.begin_group(indent, open)
172 self.begin_group(indent, open)
158 try:
173 try:
159 yield
174 yield
160 finally:
175 finally:
161 self.end_group(indent, close)
176 self.end_group(indent, close)
162
177
163 class PrettyPrinter(_PrettyPrinterBase):
178 class PrettyPrinter(_PrettyPrinterBase):
164 """
179 """
165 Baseclass for the `RepresentationPrinter` prettyprinter that is used to
180 Baseclass for the `RepresentationPrinter` prettyprinter that is used to
166 generate pretty reprs of objects. Contrary to the `RepresentationPrinter`
181 generate pretty reprs of objects. Contrary to the `RepresentationPrinter`
167 this printer knows nothing about the default pprinters or the `_repr_pretty_`
182 this printer knows nothing about the default pprinters or the `_repr_pretty_`
168 callback method.
183 callback method.
169 """
184 """
170
185
171 def __init__(self, output, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH):
186 def __init__(self, output, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH):
172 self.output = output
187 self.output = output
173 self.max_width = max_width
188 self.max_width = max_width
174 self.newline = newline
189 self.newline = newline
175 self.max_seq_length = max_seq_length
190 self.max_seq_length = max_seq_length
176 self.output_width = 0
191 self.output_width = 0
177 self.buffer_width = 0
192 self.buffer_width = 0
178 self.buffer = deque()
193 self.buffer = deque()
179
194
180 root_group = Group(0)
195 root_group = Group(0)
181 self.group_stack = [root_group]
196 self.group_stack = [root_group]
182 self.group_queue = GroupQueue(root_group)
197 self.group_queue = GroupQueue(root_group)
183 self.indentation = 0
198 self.indentation = 0
184
199
185 def _break_outer_groups(self):
200 def _break_outer_groups(self):
186 while self.max_width < self.output_width + self.buffer_width:
201 while self.max_width < self.output_width + self.buffer_width:
187 group = self.group_queue.deq()
202 group = self.group_queue.deq()
188 if not group:
203 if not group:
189 return
204 return
190 while group.breakables:
205 while group.breakables:
191 x = self.buffer.popleft()
206 x = self.buffer.popleft()
192 self.output_width = x.output(self.output, self.output_width)
207 self.output_width = x.output(self.output, self.output_width)
193 self.buffer_width -= x.width
208 self.buffer_width -= x.width
194 while self.buffer and isinstance(self.buffer[0], Text):
209 while self.buffer and isinstance(self.buffer[0], Text):
195 x = self.buffer.popleft()
210 x = self.buffer.popleft()
196 self.output_width = x.output(self.output, self.output_width)
211 self.output_width = x.output(self.output, self.output_width)
197 self.buffer_width -= x.width
212 self.buffer_width -= x.width
198
213
199 def text(self, obj):
214 def text(self, obj):
200 """Add literal text to the output."""
215 """Add literal text to the output."""
201 width = len(obj)
216 width = len(obj)
202 if self.buffer:
217 if self.buffer:
203 text = self.buffer[-1]
218 text = self.buffer[-1]
204 if not isinstance(text, Text):
219 if not isinstance(text, Text):
205 text = Text()
220 text = Text()
206 self.buffer.append(text)
221 self.buffer.append(text)
207 text.add(obj, width)
222 text.add(obj, width)
208 self.buffer_width += width
223 self.buffer_width += width
209 self._break_outer_groups()
224 self._break_outer_groups()
210 else:
225 else:
211 self.output.write(obj)
226 self.output.write(obj)
212 self.output_width += width
227 self.output_width += width
213
228
214 def breakable(self, sep=' '):
229 def breakable(self, sep=' '):
215 """
230 """
216 Add a breakable separator to the output. This does not mean that it
231 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
232 will automatically break here. If no breaking on this position takes
218 place the `sep` is inserted which default to one space.
233 place the `sep` is inserted which default to one space.
219 """
234 """
220 width = len(sep)
235 width = len(sep)
221 group = self.group_stack[-1]
236 group = self.group_stack[-1]
222 if group.want_break:
237 if group.want_break:
223 self.flush()
238 self.flush()
224 self.output.write(self.newline)
239 self.output.write(self.newline)
225 self.output.write(' ' * self.indentation)
240 self.output.write(' ' * self.indentation)
226 self.output_width = self.indentation
241 self.output_width = self.indentation
227 self.buffer_width = 0
242 self.buffer_width = 0
228 else:
243 else:
229 self.buffer.append(Breakable(sep, width, self))
244 self.buffer.append(Breakable(sep, width, self))
230 self.buffer_width += width
245 self.buffer_width += width
231 self._break_outer_groups()
246 self._break_outer_groups()
232
247
233 def break_(self):
248 def break_(self):
234 """
249 """
235 Explicitly insert a newline into the output, maintaining correct indentation.
250 Explicitly insert a newline into the output, maintaining correct indentation.
236 """
251 """
237 self.flush()
252 self.flush()
238 self.output.write(self.newline)
253 self.output.write(self.newline)
239 self.output.write(' ' * self.indentation)
254 self.output.write(' ' * self.indentation)
240 self.output_width = self.indentation
255 self.output_width = self.indentation
241 self.buffer_width = 0
256 self.buffer_width = 0
242
257
243
258
244 def begin_group(self, indent=0, open=''):
259 def begin_group(self, indent=0, open=''):
245 """
260 """
246 Begin a group. If you want support for python < 2.5 which doesn't has
261 Begin a group. If you want support for python < 2.5 which doesn't has
247 the with statement this is the preferred way:
262 the with statement this is the preferred way:
248
263
249 p.begin_group(1, '{')
264 p.begin_group(1, '{')
250 ...
265 ...
251 p.end_group(1, '}')
266 p.end_group(1, '}')
252
267
253 The python 2.5 expression would be this:
268 The python 2.5 expression would be this:
254
269
255 with p.group(1, '{', '}'):
270 with p.group(1, '{', '}'):
256 ...
271 ...
257
272
258 The first parameter specifies the indentation for the next line (usually
273 The first parameter specifies the indentation for the next line (usually
259 the width of the opening text), the second the opening text. All
274 the width of the opening text), the second the opening text. All
260 parameters are optional.
275 parameters are optional.
261 """
276 """
262 if open:
277 if open:
263 self.text(open)
278 self.text(open)
264 group = Group(self.group_stack[-1].depth + 1)
279 group = Group(self.group_stack[-1].depth + 1)
265 self.group_stack.append(group)
280 self.group_stack.append(group)
266 self.group_queue.enq(group)
281 self.group_queue.enq(group)
267 self.indentation += indent
282 self.indentation += indent
268
283
269 def _enumerate(self, seq):
284 def _enumerate(self, seq):
270 """like enumerate, but with an upper limit on the number of items"""
285 """like enumerate, but with an upper limit on the number of items"""
271 for idx, x in enumerate(seq):
286 for idx, x in enumerate(seq):
272 if self.max_seq_length and idx >= self.max_seq_length:
287 if self.max_seq_length and idx >= self.max_seq_length:
273 self.text(',')
288 self.text(',')
274 self.breakable()
289 self.breakable()
275 self.text('...')
290 self.text('...')
276 return
291 return
277 yield idx, x
292 yield idx, x
278
293
279 def end_group(self, dedent=0, close=''):
294 def end_group(self, dedent=0, close=''):
280 """End a group. See `begin_group` for more details."""
295 """End a group. See `begin_group` for more details."""
281 self.indentation -= dedent
296 self.indentation -= dedent
282 group = self.group_stack.pop()
297 group = self.group_stack.pop()
283 if not group.breakables:
298 if not group.breakables:
284 self.group_queue.remove(group)
299 self.group_queue.remove(group)
285 if close:
300 if close:
286 self.text(close)
301 self.text(close)
287
302
288 def flush(self):
303 def flush(self):
289 """Flush data that is left in the buffer."""
304 """Flush data that is left in the buffer."""
290 for data in self.buffer:
305 for data in self.buffer:
291 self.output_width += data.output(self.output, self.output_width)
306 self.output_width += data.output(self.output, self.output_width)
292 self.buffer.clear()
307 self.buffer.clear()
293 self.buffer_width = 0
308 self.buffer_width = 0
294
309
295
310
296 def _get_mro(obj_class):
311 def _get_mro(obj_class):
297 """ Get a reasonable method resolution order of a class and its superclasses
312 """ Get a reasonable method resolution order of a class and its superclasses
298 for both old-style and new-style classes.
313 for both old-style and new-style classes.
299 """
314 """
300 if not hasattr(obj_class, '__mro__'):
315 if not hasattr(obj_class, '__mro__'):
301 # Old-style class. Mix in object to make a fake new-style class.
316 # Old-style class. Mix in object to make a fake new-style class.
302 try:
317 try:
303 obj_class = type(obj_class.__name__, (obj_class, object), {})
318 obj_class = type(obj_class.__name__, (obj_class, object), {})
304 except TypeError:
319 except TypeError:
305 # Old-style extension type that does not descend from object.
320 # Old-style extension type that does not descend from object.
306 # FIXME: try to construct a more thorough MRO.
321 # FIXME: try to construct a more thorough MRO.
307 mro = [obj_class]
322 mro = [obj_class]
308 else:
323 else:
309 mro = obj_class.__mro__[1:-1]
324 mro = obj_class.__mro__[1:-1]
310 else:
325 else:
311 mro = obj_class.__mro__
326 mro = obj_class.__mro__
312 return mro
327 return mro
313
328
314
329
315 class RepresentationPrinter(PrettyPrinter):
330 class RepresentationPrinter(PrettyPrinter):
316 """
331 """
317 Special pretty printer that has a `pretty` method that calls the pretty
332 Special pretty printer that has a `pretty` method that calls the pretty
318 printer for a python object.
333 printer for a python object.
319
334
320 This class stores processing data on `self` so you must *never* use
335 This class stores processing data on `self` so you must *never* use
321 this class in a threaded environment. Always lock it or reinstanciate
336 this class in a threaded environment. Always lock it or reinstanciate
322 it.
337 it.
323
338
324 Instances also have a verbose flag callbacks can access to control their
339 Instances also have a verbose flag callbacks can access to control their
325 output. For example the default instance repr prints all attributes and
340 output. For example the default instance repr prints all attributes and
326 methods that are not prefixed by an underscore if the printer is in
341 methods that are not prefixed by an underscore if the printer is in
327 verbose mode.
342 verbose mode.
328 """
343 """
329
344
330 def __init__(self, output, verbose=False, max_width=79, newline='\n',
345 def __init__(self, output, verbose=False, max_width=79, newline='\n',
331 singleton_pprinters=None, type_pprinters=None, deferred_pprinters=None,
346 singleton_pprinters=None, type_pprinters=None, deferred_pprinters=None,
332 max_seq_length=MAX_SEQ_LENGTH):
347 max_seq_length=MAX_SEQ_LENGTH):
333
348
334 PrettyPrinter.__init__(self, output, max_width, newline, max_seq_length=max_seq_length)
349 PrettyPrinter.__init__(self, output, max_width, newline, max_seq_length=max_seq_length)
335 self.verbose = verbose
350 self.verbose = verbose
336 self.stack = []
351 self.stack = []
337 if singleton_pprinters is None:
352 if singleton_pprinters is None:
338 singleton_pprinters = _singleton_pprinters.copy()
353 singleton_pprinters = _singleton_pprinters.copy()
339 self.singleton_pprinters = singleton_pprinters
354 self.singleton_pprinters = singleton_pprinters
340 if type_pprinters is None:
355 if type_pprinters is None:
341 type_pprinters = _type_pprinters.copy()
356 type_pprinters = _type_pprinters.copy()
342 self.type_pprinters = type_pprinters
357 self.type_pprinters = type_pprinters
343 if deferred_pprinters is None:
358 if deferred_pprinters is None:
344 deferred_pprinters = _deferred_type_pprinters.copy()
359 deferred_pprinters = _deferred_type_pprinters.copy()
345 self.deferred_pprinters = deferred_pprinters
360 self.deferred_pprinters = deferred_pprinters
346
361
347 def pretty(self, obj):
362 def pretty(self, obj):
348 """Pretty print the given object."""
363 """Pretty print the given object."""
349 obj_id = id(obj)
364 obj_id = id(obj)
350 cycle = obj_id in self.stack
365 cycle = obj_id in self.stack
351 self.stack.append(obj_id)
366 self.stack.append(obj_id)
352 self.begin_group()
367 self.begin_group()
353 try:
368 try:
354 obj_class = _safe_getattr(obj, '__class__', None) or type(obj)
369 obj_class = _safe_getattr(obj, '__class__', None) or type(obj)
355 # First try to find registered singleton printers for the type.
370 # First try to find registered singleton printers for the type.
356 try:
371 try:
357 printer = self.singleton_pprinters[obj_id]
372 printer = self.singleton_pprinters[obj_id]
358 except (TypeError, KeyError):
373 except (TypeError, KeyError):
359 pass
374 pass
360 else:
375 else:
361 return printer(obj, self, cycle)
376 return printer(obj, self, cycle)
362 # Next walk the mro and check for either:
377 # Next walk the mro and check for either:
363 # 1) a registered printer
378 # 1) a registered printer
364 # 2) a _repr_pretty_ method
379 # 2) a _repr_pretty_ method
365 for cls in _get_mro(obj_class):
380 for cls in _get_mro(obj_class):
366 if cls in self.type_pprinters:
381 if cls in self.type_pprinters:
367 # printer registered in self.type_pprinters
382 # printer registered in self.type_pprinters
368 return self.type_pprinters[cls](obj, self, cycle)
383 return self.type_pprinters[cls](obj, self, cycle)
369 else:
384 else:
370 # deferred printer
385 # deferred printer
371 printer = self._in_deferred_types(cls)
386 printer = self._in_deferred_types(cls)
372 if printer is not None:
387 if printer is not None:
373 return printer(obj, self, cycle)
388 return printer(obj, self, cycle)
374 else:
389 else:
375 # Finally look for special method names.
390 # Finally look for special method names.
376 # Some objects automatically create any requested
391 # Some objects automatically create any requested
377 # attribute. Try to ignore most of them by checking for
392 # attribute. Try to ignore most of them by checking for
378 # callability.
393 # callability.
379 if '_repr_pretty_' in cls.__dict__:
394 if '_repr_pretty_' in cls.__dict__:
380 meth = cls._repr_pretty_
395 meth = cls._repr_pretty_
381 if callable(meth):
396 if callable(meth):
382 return meth(obj, self, cycle)
397 return meth(obj, self, cycle)
383 return _default_pprint(obj, self, cycle)
398 return _default_pprint(obj, self, cycle)
384 finally:
399 finally:
385 self.end_group()
400 self.end_group()
386 self.stack.pop()
401 self.stack.pop()
387
402
388 def _in_deferred_types(self, cls):
403 def _in_deferred_types(self, cls):
389 """
404 """
390 Check if the given class is specified in the deferred type registry.
405 Check if the given class is specified in the deferred type registry.
391
406
392 Returns the printer from the registry if it exists, and None if the
407 Returns the printer from the registry if it exists, and None if the
393 class is not in the registry. Successful matches will be moved to the
408 class is not in the registry. Successful matches will be moved to the
394 regular type registry for future use.
409 regular type registry for future use.
395 """
410 """
396 mod = _safe_getattr(cls, '__module__', None)
411 mod = _safe_getattr(cls, '__module__', None)
397 name = _safe_getattr(cls, '__name__', None)
412 name = _safe_getattr(cls, '__name__', None)
398 key = (mod, name)
413 key = (mod, name)
399 printer = None
414 printer = None
400 if key in self.deferred_pprinters:
415 if key in self.deferred_pprinters:
401 # Move the printer over to the regular registry.
416 # Move the printer over to the regular registry.
402 printer = self.deferred_pprinters.pop(key)
417 printer = self.deferred_pprinters.pop(key)
403 self.type_pprinters[cls] = printer
418 self.type_pprinters[cls] = printer
404 return printer
419 return printer
405
420
406
421
407 class Printable(object):
422 class Printable(object):
408
423
409 def output(self, stream, output_width):
424 def output(self, stream, output_width):
410 return output_width
425 return output_width
411
426
412
427
413 class Text(Printable):
428 class Text(Printable):
414
429
415 def __init__(self):
430 def __init__(self):
416 self.objs = []
431 self.objs = []
417 self.width = 0
432 self.width = 0
418
433
419 def output(self, stream, output_width):
434 def output(self, stream, output_width):
420 for obj in self.objs:
435 for obj in self.objs:
421 stream.write(obj)
436 stream.write(obj)
422 return output_width + self.width
437 return output_width + self.width
423
438
424 def add(self, obj, width):
439 def add(self, obj, width):
425 self.objs.append(obj)
440 self.objs.append(obj)
426 self.width += width
441 self.width += width
427
442
428
443
429 class Breakable(Printable):
444 class Breakable(Printable):
430
445
431 def __init__(self, seq, width, pretty):
446 def __init__(self, seq, width, pretty):
432 self.obj = seq
447 self.obj = seq
433 self.width = width
448 self.width = width
434 self.pretty = pretty
449 self.pretty = pretty
435 self.indentation = pretty.indentation
450 self.indentation = pretty.indentation
436 self.group = pretty.group_stack[-1]
451 self.group = pretty.group_stack[-1]
437 self.group.breakables.append(self)
452 self.group.breakables.append(self)
438
453
439 def output(self, stream, output_width):
454 def output(self, stream, output_width):
440 self.group.breakables.popleft()
455 self.group.breakables.popleft()
441 if self.group.want_break:
456 if self.group.want_break:
442 stream.write(self.pretty.newline)
457 stream.write(self.pretty.newline)
443 stream.write(' ' * self.indentation)
458 stream.write(' ' * self.indentation)
444 return self.indentation
459 return self.indentation
445 if not self.group.breakables:
460 if not self.group.breakables:
446 self.pretty.group_queue.remove(self.group)
461 self.pretty.group_queue.remove(self.group)
447 stream.write(self.obj)
462 stream.write(self.obj)
448 return output_width + self.width
463 return output_width + self.width
449
464
450
465
451 class Group(Printable):
466 class Group(Printable):
452
467
453 def __init__(self, depth):
468 def __init__(self, depth):
454 self.depth = depth
469 self.depth = depth
455 self.breakables = deque()
470 self.breakables = deque()
456 self.want_break = False
471 self.want_break = False
457
472
458
473
459 class GroupQueue(object):
474 class GroupQueue(object):
460
475
461 def __init__(self, *groups):
476 def __init__(self, *groups):
462 self.queue = []
477 self.queue = []
463 for group in groups:
478 for group in groups:
464 self.enq(group)
479 self.enq(group)
465
480
466 def enq(self, group):
481 def enq(self, group):
467 depth = group.depth
482 depth = group.depth
468 while depth > len(self.queue) - 1:
483 while depth > len(self.queue) - 1:
469 self.queue.append([])
484 self.queue.append([])
470 self.queue[depth].append(group)
485 self.queue[depth].append(group)
471
486
472 def deq(self):
487 def deq(self):
473 for stack in self.queue:
488 for stack in self.queue:
474 for idx, group in enumerate(reversed(stack)):
489 for idx, group in enumerate(reversed(stack)):
475 if group.breakables:
490 if group.breakables:
476 del stack[idx]
491 del stack[idx]
477 group.want_break = True
492 group.want_break = True
478 return group
493 return group
479 for group in stack:
494 for group in stack:
480 group.want_break = True
495 group.want_break = True
481 del stack[:]
496 del stack[:]
482
497
483 def remove(self, group):
498 def remove(self, group):
484 try:
499 try:
485 self.queue[group.depth].remove(group)
500 self.queue[group.depth].remove(group)
486 except ValueError:
501 except ValueError:
487 pass
502 pass
488
503
489 try:
504 try:
490 _baseclass_reprs = (object.__repr__, types.InstanceType.__repr__)
505 _baseclass_reprs = (object.__repr__, types.InstanceType.__repr__)
491 except AttributeError: # Python 3
506 except AttributeError: # Python 3
492 _baseclass_reprs = (object.__repr__,)
507 _baseclass_reprs = (object.__repr__,)
493
508
494
509
495 def _default_pprint(obj, p, cycle):
510 def _default_pprint(obj, p, cycle):
496 """
511 """
497 The default print function. Used if an object does not provide one and
512 The default print function. Used if an object does not provide one and
498 it's none of the builtin objects.
513 it's none of the builtin objects.
499 """
514 """
500 klass = _safe_getattr(obj, '__class__', None) or type(obj)
515 klass = _safe_getattr(obj, '__class__', None) or type(obj)
501 if _safe_getattr(klass, '__repr__', None) not in _baseclass_reprs:
516 if _safe_getattr(klass, '__repr__', None) not in _baseclass_reprs:
502 # A user-provided repr. Find newlines and replace them with p.break_()
517 # A user-provided repr. Find newlines and replace them with p.break_()
503 _repr_pprint(obj, p, cycle)
518 _repr_pprint(obj, p, cycle)
504 return
519 return
505 p.begin_group(1, '<')
520 p.begin_group(1, '<')
506 p.pretty(klass)
521 p.pretty(klass)
507 p.text(' at 0x%x' % id(obj))
522 p.text(' at 0x%x' % id(obj))
508 if cycle:
523 if cycle:
509 p.text(' ...')
524 p.text(' ...')
510 elif p.verbose:
525 elif p.verbose:
511 first = True
526 first = True
512 for key in dir(obj):
527 for key in dir(obj):
513 if not key.startswith('_'):
528 if not key.startswith('_'):
514 try:
529 try:
515 value = getattr(obj, key)
530 value = getattr(obj, key)
516 except AttributeError:
531 except AttributeError:
517 continue
532 continue
518 if isinstance(value, types.MethodType):
533 if isinstance(value, types.MethodType):
519 continue
534 continue
520 if not first:
535 if not first:
521 p.text(',')
536 p.text(',')
522 p.breakable()
537 p.breakable()
523 p.text(key)
538 p.text(key)
524 p.text('=')
539 p.text('=')
525 step = len(key) + 1
540 step = len(key) + 1
526 p.indentation += step
541 p.indentation += step
527 p.pretty(value)
542 p.pretty(value)
528 p.indentation -= step
543 p.indentation -= step
529 first = False
544 first = False
530 p.end_group(1, '>')
545 p.end_group(1, '>')
531
546
532
547
533 def _seq_pprinter_factory(start, end, basetype):
548 def _seq_pprinter_factory(start, end, basetype):
534 """
549 """
535 Factory that returns a pprint function useful for sequences. Used by
550 Factory that returns a pprint function useful for sequences. Used by
536 the default pprint for tuples, dicts, and lists.
551 the default pprint for tuples, dicts, and lists.
537 """
552 """
538 def inner(obj, p, cycle):
553 def inner(obj, p, cycle):
539 typ = type(obj)
554 typ = type(obj)
540 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
555 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
541 # If the subclass provides its own repr, use it instead.
556 # If the subclass provides its own repr, use it instead.
542 return p.text(typ.__repr__(obj))
557 return p.text(typ.__repr__(obj))
543
558
544 if cycle:
559 if cycle:
545 return p.text(start + '...' + end)
560 return p.text(start + '...' + end)
546 step = len(start)
561 step = len(start)
547 p.begin_group(step, start)
562 p.begin_group(step, start)
548 for idx, x in p._enumerate(obj):
563 for idx, x in p._enumerate(obj):
549 if idx:
564 if idx:
550 p.text(',')
565 p.text(',')
551 p.breakable()
566 p.breakable()
552 p.pretty(x)
567 p.pretty(x)
553 if len(obj) == 1 and type(obj) is tuple:
568 if len(obj) == 1 and type(obj) is tuple:
554 # Special case for 1-item tuples.
569 # Special case for 1-item tuples.
555 p.text(',')
570 p.text(',')
556 p.end_group(step, end)
571 p.end_group(step, end)
557 return inner
572 return inner
558
573
559
574
560 def _set_pprinter_factory(start, end, basetype):
575 def _set_pprinter_factory(start, end, basetype):
561 """
576 """
562 Factory that returns a pprint function useful for sets and frozensets.
577 Factory that returns a pprint function useful for sets and frozensets.
563 """
578 """
564 def inner(obj, p, cycle):
579 def inner(obj, p, cycle):
565 typ = type(obj)
580 typ = type(obj)
566 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
581 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
567 # If the subclass provides its own repr, use it instead.
582 # If the subclass provides its own repr, use it instead.
568 return p.text(typ.__repr__(obj))
583 return p.text(typ.__repr__(obj))
569
584
570 if cycle:
585 if cycle:
571 return p.text(start + '...' + end)
586 return p.text(start + '...' + end)
572 if len(obj) == 0:
587 if len(obj) == 0:
573 # Special case.
588 # Special case.
574 p.text(basetype.__name__ + '()')
589 p.text(basetype.__name__ + '()')
575 else:
590 else:
576 step = len(start)
591 step = len(start)
577 p.begin_group(step, start)
592 p.begin_group(step, start)
578 # Like dictionary keys, we will try to sort the items if there aren't too many
593 # Like dictionary keys, we will try to sort the items if there aren't too many
579 items = obj
580 if not (p.max_seq_length and len(obj) >= p.max_seq_length):
594 if not (p.max_seq_length and len(obj) >= p.max_seq_length):
581 try:
595 items = _sorted_for_pprint(obj)
582 items = sorted(obj)
596 else:
583 except Exception:
597 items = obj
584 # Sometimes the items don't sort.
585 pass
586 for idx, x in p._enumerate(items):
598 for idx, x in p._enumerate(items):
587 if idx:
599 if idx:
588 p.text(',')
600 p.text(',')
589 p.breakable()
601 p.breakable()
590 p.pretty(x)
602 p.pretty(x)
591 p.end_group(step, end)
603 p.end_group(step, end)
592 return inner
604 return inner
593
605
594
606
595 def _dict_pprinter_factory(start, end, basetype=None):
607 def _dict_pprinter_factory(start, end, basetype=None):
596 """
608 """
597 Factory that returns a pprint function used by the default pprint of
609 Factory that returns a pprint function used by the default pprint of
598 dicts and dict proxies.
610 dicts and dict proxies.
599 """
611 """
600 def inner(obj, p, cycle):
612 def inner(obj, p, cycle):
601 typ = type(obj)
613 typ = type(obj)
602 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
614 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
603 # If the subclass provides its own repr, use it instead.
615 # If the subclass provides its own repr, use it instead.
604 return p.text(typ.__repr__(obj))
616 return p.text(typ.__repr__(obj))
605
617
606 if cycle:
618 if cycle:
607 return p.text('{...}')
619 return p.text('{...}')
608 step = len(start)
620 step = len(start)
609 p.begin_group(step, start)
621 p.begin_group(step, start)
610 keys = obj.keys()
622 keys = obj.keys()
611 # if dict isn't large enough to be truncated, sort keys before displaying
623 # if dict isn't large enough to be truncated, sort keys before displaying
612 if not (p.max_seq_length and len(obj) >= p.max_seq_length):
624 if not (p.max_seq_length and len(obj) >= p.max_seq_length):
613 try:
625 keys = _sorted_for_pprint(keys)
614 keys = sorted(keys)
615 except Exception:
616 # Sometimes the keys don't sort.
617 pass
618 for idx, key in p._enumerate(keys):
626 for idx, key in p._enumerate(keys):
619 if idx:
627 if idx:
620 p.text(',')
628 p.text(',')
621 p.breakable()
629 p.breakable()
622 p.pretty(key)
630 p.pretty(key)
623 p.text(': ')
631 p.text(': ')
624 p.pretty(obj[key])
632 p.pretty(obj[key])
625 p.end_group(step, end)
633 p.end_group(step, end)
626 return inner
634 return inner
627
635
628
636
629 def _super_pprint(obj, p, cycle):
637 def _super_pprint(obj, p, cycle):
630 """The pprint for the super type."""
638 """The pprint for the super type."""
631 p.begin_group(8, '<super: ')
639 p.begin_group(8, '<super: ')
632 p.pretty(obj.__thisclass__)
640 p.pretty(obj.__thisclass__)
633 p.text(',')
641 p.text(',')
634 p.breakable()
642 p.breakable()
635 if PYPY: # In PyPy, super() objects don't have __self__ attributes
643 if PYPY: # In PyPy, super() objects don't have __self__ attributes
636 dself = obj.__repr__.__self__
644 dself = obj.__repr__.__self__
637 p.pretty(None if dself is obj else dself)
645 p.pretty(None if dself is obj else dself)
638 else:
646 else:
639 p.pretty(obj.__self__)
647 p.pretty(obj.__self__)
640 p.end_group(8, '>')
648 p.end_group(8, '>')
641
649
642
650
643 def _re_pattern_pprint(obj, p, cycle):
651 def _re_pattern_pprint(obj, p, cycle):
644 """The pprint function for regular expression patterns."""
652 """The pprint function for regular expression patterns."""
645 p.text('re.compile(')
653 p.text('re.compile(')
646 pattern = repr(obj.pattern)
654 pattern = repr(obj.pattern)
647 if pattern[:1] in 'uU':
655 if pattern[:1] in 'uU':
648 pattern = pattern[1:]
656 pattern = pattern[1:]
649 prefix = 'ur'
657 prefix = 'ur'
650 else:
658 else:
651 prefix = 'r'
659 prefix = 'r'
652 pattern = prefix + pattern.replace('\\\\', '\\')
660 pattern = prefix + pattern.replace('\\\\', '\\')
653 p.text(pattern)
661 p.text(pattern)
654 if obj.flags:
662 if obj.flags:
655 p.text(',')
663 p.text(',')
656 p.breakable()
664 p.breakable()
657 done_one = False
665 done_one = False
658 for flag in ('TEMPLATE', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL',
666 for flag in ('TEMPLATE', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL',
659 'UNICODE', 'VERBOSE', 'DEBUG'):
667 'UNICODE', 'VERBOSE', 'DEBUG'):
660 if obj.flags & getattr(re, flag):
668 if obj.flags & getattr(re, flag):
661 if done_one:
669 if done_one:
662 p.text('|')
670 p.text('|')
663 p.text('re.' + flag)
671 p.text('re.' + flag)
664 done_one = True
672 done_one = True
665 p.text(')')
673 p.text(')')
666
674
667
675
668 def _type_pprint(obj, p, cycle):
676 def _type_pprint(obj, p, cycle):
669 """The pprint for classes and types."""
677 """The pprint for classes and types."""
670 # Heap allocated types might not have the module attribute,
678 # Heap allocated types might not have the module attribute,
671 # and others may set it to None.
679 # and others may set it to None.
672
680
673 # Checks for a __repr__ override in the metaclass. Can't compare the
681 # Checks for a __repr__ override in the metaclass. Can't compare the
674 # type(obj).__repr__ directly because in PyPy the representation function
682 # type(obj).__repr__ directly because in PyPy the representation function
675 # inherited from type isn't the same type.__repr__
683 # inherited from type isn't the same type.__repr__
676 if [m for m in _get_mro(type(obj)) if "__repr__" in vars(m)][:1] != [type]:
684 if [m for m in _get_mro(type(obj)) if "__repr__" in vars(m)][:1] != [type]:
677 _repr_pprint(obj, p, cycle)
685 _repr_pprint(obj, p, cycle)
678 return
686 return
679
687
680 mod = _safe_getattr(obj, '__module__', None)
688 mod = _safe_getattr(obj, '__module__', None)
681 try:
689 try:
682 name = obj.__qualname__
690 name = obj.__qualname__
683 if not isinstance(name, string_types):
691 if not isinstance(name, string_types):
684 # This can happen if the type implements __qualname__ as a property
692 # This can happen if the type implements __qualname__ as a property
685 # or other descriptor in Python 2.
693 # or other descriptor in Python 2.
686 raise Exception("Try __name__")
694 raise Exception("Try __name__")
687 except Exception:
695 except Exception:
688 name = obj.__name__
696 name = obj.__name__
689 if not isinstance(name, string_types):
697 if not isinstance(name, string_types):
690 name = '<unknown type>'
698 name = '<unknown type>'
691
699
692 if mod in (None, '__builtin__', 'builtins', 'exceptions'):
700 if mod in (None, '__builtin__', 'builtins', 'exceptions'):
693 p.text(name)
701 p.text(name)
694 else:
702 else:
695 p.text(mod + '.' + name)
703 p.text(mod + '.' + name)
696
704
697
705
698 def _repr_pprint(obj, p, cycle):
706 def _repr_pprint(obj, p, cycle):
699 """A pprint that just redirects to the normal repr function."""
707 """A pprint that just redirects to the normal repr function."""
700 # Find newlines and replace them with p.break_()
708 # Find newlines and replace them with p.break_()
701 output = repr(obj)
709 output = repr(obj)
702 for idx,output_line in enumerate(output.splitlines()):
710 for idx,output_line in enumerate(output.splitlines()):
703 if idx:
711 if idx:
704 p.break_()
712 p.break_()
705 p.text(output_line)
713 p.text(output_line)
706
714
707
715
708 def _function_pprint(obj, p, cycle):
716 def _function_pprint(obj, p, cycle):
709 """Base pprint for all functions and builtin functions."""
717 """Base pprint for all functions and builtin functions."""
710 name = _safe_getattr(obj, '__qualname__', obj.__name__)
718 name = _safe_getattr(obj, '__qualname__', obj.__name__)
711 mod = obj.__module__
719 mod = obj.__module__
712 if mod and mod not in ('__builtin__', 'builtins', 'exceptions'):
720 if mod and mod not in ('__builtin__', 'builtins', 'exceptions'):
713 name = mod + '.' + name
721 name = mod + '.' + name
714 p.text('<function %s>' % name)
722 p.text('<function %s>' % name)
715
723
716
724
717 def _exception_pprint(obj, p, cycle):
725 def _exception_pprint(obj, p, cycle):
718 """Base pprint for all exceptions."""
726 """Base pprint for all exceptions."""
719 name = getattr(obj.__class__, '__qualname__', obj.__class__.__name__)
727 name = getattr(obj.__class__, '__qualname__', obj.__class__.__name__)
720 if obj.__class__.__module__ not in ('exceptions', 'builtins'):
728 if obj.__class__.__module__ not in ('exceptions', 'builtins'):
721 name = '%s.%s' % (obj.__class__.__module__, name)
729 name = '%s.%s' % (obj.__class__.__module__, name)
722 step = len(name) + 1
730 step = len(name) + 1
723 p.begin_group(step, name + '(')
731 p.begin_group(step, name + '(')
724 for idx, arg in enumerate(getattr(obj, 'args', ())):
732 for idx, arg in enumerate(getattr(obj, 'args', ())):
725 if idx:
733 if idx:
726 p.text(',')
734 p.text(',')
727 p.breakable()
735 p.breakable()
728 p.pretty(arg)
736 p.pretty(arg)
729 p.end_group(step, ')')
737 p.end_group(step, ')')
730
738
731
739
732 #: the exception base
740 #: the exception base
733 try:
741 try:
734 _exception_base = BaseException
742 _exception_base = BaseException
735 except NameError:
743 except NameError:
736 _exception_base = Exception
744 _exception_base = Exception
737
745
738
746
739 #: printers for builtin types
747 #: printers for builtin types
740 _type_pprinters = {
748 _type_pprinters = {
741 int: _repr_pprint,
749 int: _repr_pprint,
742 float: _repr_pprint,
750 float: _repr_pprint,
743 str: _repr_pprint,
751 str: _repr_pprint,
744 tuple: _seq_pprinter_factory('(', ')', tuple),
752 tuple: _seq_pprinter_factory('(', ')', tuple),
745 list: _seq_pprinter_factory('[', ']', list),
753 list: _seq_pprinter_factory('[', ']', list),
746 dict: _dict_pprinter_factory('{', '}', dict),
754 dict: _dict_pprinter_factory('{', '}', dict),
747
755
748 set: _set_pprinter_factory('{', '}', set),
756 set: _set_pprinter_factory('{', '}', set),
749 frozenset: _set_pprinter_factory('frozenset({', '})', frozenset),
757 frozenset: _set_pprinter_factory('frozenset({', '})', frozenset),
750 super: _super_pprint,
758 super: _super_pprint,
751 _re_pattern_type: _re_pattern_pprint,
759 _re_pattern_type: _re_pattern_pprint,
752 type: _type_pprint,
760 type: _type_pprint,
753 types.FunctionType: _function_pprint,
761 types.FunctionType: _function_pprint,
754 types.BuiltinFunctionType: _function_pprint,
762 types.BuiltinFunctionType: _function_pprint,
755 types.MethodType: _repr_pprint,
763 types.MethodType: _repr_pprint,
756
764
757 datetime.datetime: _repr_pprint,
765 datetime.datetime: _repr_pprint,
758 datetime.timedelta: _repr_pprint,
766 datetime.timedelta: _repr_pprint,
759 _exception_base: _exception_pprint
767 _exception_base: _exception_pprint
760 }
768 }
761
769
762 try:
770 try:
763 # In PyPy, types.DictProxyType is dict, setting the dictproxy printer
771 # In PyPy, types.DictProxyType is dict, setting the dictproxy printer
764 # using dict.setdefault avoids overwritting the dict printer
772 # using dict.setdefault avoids overwritting the dict printer
765 _type_pprinters.setdefault(types.DictProxyType,
773 _type_pprinters.setdefault(types.DictProxyType,
766 _dict_pprinter_factory('dict_proxy({', '})'))
774 _dict_pprinter_factory('dict_proxy({', '})'))
767 _type_pprinters[types.ClassType] = _type_pprint
775 _type_pprinters[types.ClassType] = _type_pprint
768 _type_pprinters[types.SliceType] = _repr_pprint
776 _type_pprinters[types.SliceType] = _repr_pprint
769 except AttributeError: # Python 3
777 except AttributeError: # Python 3
770 _type_pprinters[types.MappingProxyType] = \
778 _type_pprinters[types.MappingProxyType] = \
771 _dict_pprinter_factory('mappingproxy({', '})')
779 _dict_pprinter_factory('mappingproxy({', '})')
772 _type_pprinters[slice] = _repr_pprint
780 _type_pprinters[slice] = _repr_pprint
773
781
774 try:
782 try:
775 _type_pprinters[xrange] = _repr_pprint
783 _type_pprinters[xrange] = _repr_pprint
776 _type_pprinters[long] = _repr_pprint
784 _type_pprinters[long] = _repr_pprint
777 _type_pprinters[unicode] = _repr_pprint
785 _type_pprinters[unicode] = _repr_pprint
778 except NameError:
786 except NameError:
779 _type_pprinters[range] = _repr_pprint
787 _type_pprinters[range] = _repr_pprint
780 _type_pprinters[bytes] = _repr_pprint
788 _type_pprinters[bytes] = _repr_pprint
781
789
782 #: printers for types specified by name
790 #: printers for types specified by name
783 _deferred_type_pprinters = {
791 _deferred_type_pprinters = {
784 }
792 }
785
793
786 def for_type(typ, func):
794 def for_type(typ, func):
787 """
795 """
788 Add a pretty printer for a given type.
796 Add a pretty printer for a given type.
789 """
797 """
790 oldfunc = _type_pprinters.get(typ, None)
798 oldfunc = _type_pprinters.get(typ, None)
791 if func is not None:
799 if func is not None:
792 # To support easy restoration of old pprinters, we need to ignore Nones.
800 # To support easy restoration of old pprinters, we need to ignore Nones.
793 _type_pprinters[typ] = func
801 _type_pprinters[typ] = func
794 return oldfunc
802 return oldfunc
795
803
796 def for_type_by_name(type_module, type_name, func):
804 def for_type_by_name(type_module, type_name, func):
797 """
805 """
798 Add a pretty printer for a type specified by the module and name of a type
806 Add a pretty printer for a type specified by the module and name of a type
799 rather than the type object itself.
807 rather than the type object itself.
800 """
808 """
801 key = (type_module, type_name)
809 key = (type_module, type_name)
802 oldfunc = _deferred_type_pprinters.get(key, None)
810 oldfunc = _deferred_type_pprinters.get(key, None)
803 if func is not None:
811 if func is not None:
804 # To support easy restoration of old pprinters, we need to ignore Nones.
812 # To support easy restoration of old pprinters, we need to ignore Nones.
805 _deferred_type_pprinters[key] = func
813 _deferred_type_pprinters[key] = func
806 return oldfunc
814 return oldfunc
807
815
808
816
809 #: printers for the default singletons
817 #: printers for the default singletons
810 _singleton_pprinters = dict.fromkeys(map(id, [None, True, False, Ellipsis,
818 _singleton_pprinters = dict.fromkeys(map(id, [None, True, False, Ellipsis,
811 NotImplemented]), _repr_pprint)
819 NotImplemented]), _repr_pprint)
812
820
813
821
814 def _defaultdict_pprint(obj, p, cycle):
822 def _defaultdict_pprint(obj, p, cycle):
815 name = obj.__class__.__name__
823 name = obj.__class__.__name__
816 with p.group(len(name) + 1, name + '(', ')'):
824 with p.group(len(name) + 1, name + '(', ')'):
817 if cycle:
825 if cycle:
818 p.text('...')
826 p.text('...')
819 else:
827 else:
820 p.pretty(obj.default_factory)
828 p.pretty(obj.default_factory)
821 p.text(',')
829 p.text(',')
822 p.breakable()
830 p.breakable()
823 p.pretty(dict(obj))
831 p.pretty(dict(obj))
824
832
825 def _ordereddict_pprint(obj, p, cycle):
833 def _ordereddict_pprint(obj, p, cycle):
826 name = obj.__class__.__name__
834 name = obj.__class__.__name__
827 with p.group(len(name) + 1, name + '(', ')'):
835 with p.group(len(name) + 1, name + '(', ')'):
828 if cycle:
836 if cycle:
829 p.text('...')
837 p.text('...')
830 elif len(obj):
838 elif len(obj):
831 p.pretty(list(obj.items()))
839 p.pretty(list(obj.items()))
832
840
833 def _deque_pprint(obj, p, cycle):
841 def _deque_pprint(obj, p, cycle):
834 name = obj.__class__.__name__
842 name = obj.__class__.__name__
835 with p.group(len(name) + 1, name + '(', ')'):
843 with p.group(len(name) + 1, name + '(', ')'):
836 if cycle:
844 if cycle:
837 p.text('...')
845 p.text('...')
838 else:
846 else:
839 p.pretty(list(obj))
847 p.pretty(list(obj))
840
848
841
849
842 def _counter_pprint(obj, p, cycle):
850 def _counter_pprint(obj, p, cycle):
843 name = obj.__class__.__name__
851 name = obj.__class__.__name__
844 with p.group(len(name) + 1, name + '(', ')'):
852 with p.group(len(name) + 1, name + '(', ')'):
845 if cycle:
853 if cycle:
846 p.text('...')
854 p.text('...')
847 elif len(obj):
855 elif len(obj):
848 p.pretty(dict(obj))
856 p.pretty(dict(obj))
849
857
850 for_type_by_name('collections', 'defaultdict', _defaultdict_pprint)
858 for_type_by_name('collections', 'defaultdict', _defaultdict_pprint)
851 for_type_by_name('collections', 'OrderedDict', _ordereddict_pprint)
859 for_type_by_name('collections', 'OrderedDict', _ordereddict_pprint)
852 for_type_by_name('collections', 'deque', _deque_pprint)
860 for_type_by_name('collections', 'deque', _deque_pprint)
853 for_type_by_name('collections', 'Counter', _counter_pprint)
861 for_type_by_name('collections', 'Counter', _counter_pprint)
854
862
855 if __name__ == '__main__':
863 if __name__ == '__main__':
856 from random import randrange
864 from random import randrange
857 class Foo(object):
865 class Foo(object):
858 def __init__(self):
866 def __init__(self):
859 self.foo = 1
867 self.foo = 1
860 self.bar = re.compile(r'\s+')
868 self.bar = re.compile(r'\s+')
861 self.blub = dict.fromkeys(range(30), randrange(1, 40))
869 self.blub = dict.fromkeys(range(30), randrange(1, 40))
862 self.hehe = 23424.234234
870 self.hehe = 23424.234234
863 self.list = ["blub", "blah", self]
871 self.list = ["blub", "blah", self]
864
872
865 def get_foo(self):
873 def get_foo(self):
866 print("foo")
874 print("foo")
867
875
868 pprint(Foo(), verbose=True)
876 pprint(Foo(), verbose=True)
General Comments 0
You need to be logged in to leave comments. Login now