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