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