##// END OF EJS Templates
Merge pull request #5376 from minrk/pretty-cap...
Paul Ivanov -
r15866:11575ed2 merge
parent child Browse files
Show More
@@ -1,851 +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
126 _re_pattern_type = type(re.compile(''))
126 _re_pattern_type = type(re.compile(''))
127
127
128 def _failed_repr(obj, e):
128 def _failed_repr(obj, e):
129 """Render a failed repr, including the exception.
129 """Render a failed repr, including the exception.
130
130
131 Tries to get exception and type info
131 Tries to get exception and type info
132 """
132 """
133 # get exception name
133 # get exception name
134 if e.__class__.__module__ in ('exceptions', 'builtins'):
134 if e.__class__.__module__ in ('exceptions', 'builtins'):
135 ename = e.__class__.__name__
135 ename = e.__class__.__name__
136 else:
136 else:
137 ename = '{}.{}'.format(
137 ename = '{}.{}'.format(
138 e.__class__.__module__,
138 e.__class__.__module__,
139 e.__class__.__name__,
139 e.__class__.__name__,
140 )
140 )
141 # and exception string, which sometimes fails
141 # and exception string, which sometimes fails
142 # (usually due to unicode error message)
142 # (usually due to unicode error message)
143 try:
143 try:
144 estr = str(e)
144 estr = str(e)
145 except Exception:
145 except Exception:
146 estr = "unknown"
146 estr = "unknown"
147
147
148 # and class name
148 # and class name
149 try:
149 try:
150 klass = _safe_getattr(obj, '__class__', None) or type(obj)
150 klass = _safe_getattr(obj, '__class__', None) or type(obj)
151 mod = _safe_getattr(klass, '__module__', None)
151 mod = _safe_getattr(klass, '__module__', None)
152 if mod in (None, '__builtin__', 'builtins', 'exceptions'):
152 if mod in (None, '__builtin__', 'builtins', 'exceptions'):
153 classname = klass.__name__
153 classname = klass.__name__
154 else:
154 else:
155 classname = mod + '.' + klass.__name__
155 classname = mod + '.' + klass.__name__
156 except Exception:
156 except Exception:
157 # this may be paranoid, but we already know repr is broken
157 # this may be paranoid, but we already know repr is broken
158 classname = "unknown type"
158 classname = "unknown type"
159
159
160 # the informative repr
160 # the informative repr
161 return "<repr(<{} at 0x{:x}>) failed: {}: {}>".format(
161 return "<repr(<{} at 0x{:x}>) failed: {}: {}>".format(
162 classname, id(obj), ename, estr,
162 classname, id(obj), ename, estr,
163 )
163 )
164
164
165 def _safe_repr(obj):
165 def _safe_repr(obj):
166 """Don't assume repr is not broken."""
166 """Don't assume repr is not broken."""
167 try:
167 try:
168 return repr(obj)
168 return repr(obj)
169 except Exception as e:
169 except Exception as e:
170 return _failed_repr(obj, e)
170 return _failed_repr(obj, e)
171
171
172 def _safe_getattr(obj, attr, default=None):
172 def _safe_getattr(obj, attr, default=None):
173 """Safe version of getattr.
173 """Safe version of getattr.
174
174
175 Same as getattr, but will return ``default`` on any Exception,
175 Same as getattr, but will return ``default`` on any Exception,
176 rather than raising.
176 rather than raising.
177 """
177 """
178 try:
178 try:
179 return getattr(obj, attr, default)
179 return getattr(obj, attr, default)
180 except Exception:
180 except Exception:
181 return default
181 return default
182
182
183 def pretty(obj, verbose=False, max_width=79, newline='\n'):
183 def pretty(obj, verbose=False, max_width=79, newline='\n'):
184 """
184 """
185 Pretty print the object's representation.
185 Pretty print the object's representation.
186 """
186 """
187 stream = StringIO()
187 stream = StringIO()
188 printer = RepresentationPrinter(stream, verbose, max_width, newline)
188 printer = RepresentationPrinter(stream, verbose, max_width, newline)
189 printer.pretty(obj)
189 printer.pretty(obj)
190 printer.flush()
190 printer.flush()
191 return stream.getvalue()
191 return stream.getvalue()
192
192
193
193
194 def pprint(obj, verbose=False, max_width=79, newline='\n'):
194 def pprint(obj, verbose=False, max_width=79, newline='\n'):
195 """
195 """
196 Like `pretty` but print to stdout.
196 Like `pretty` but print to stdout.
197 """
197 """
198 printer = RepresentationPrinter(sys.stdout, verbose, max_width, newline)
198 printer = RepresentationPrinter(sys.stdout, verbose, max_width, newline)
199 printer.pretty(obj)
199 printer.pretty(obj)
200 printer.flush()
200 printer.flush()
201 sys.stdout.write(newline)
201 sys.stdout.write(newline)
202 sys.stdout.flush()
202 sys.stdout.flush()
203
203
204 class _PrettyPrinterBase(object):
204 class _PrettyPrinterBase(object):
205
205
206 @contextmanager
206 @contextmanager
207 def indent(self, indent):
207 def indent(self, indent):
208 """with statement support for indenting/dedenting."""
208 """with statement support for indenting/dedenting."""
209 self.indentation += indent
209 self.indentation += indent
210 try:
210 try:
211 yield
211 yield
212 finally:
212 finally:
213 self.indentation -= indent
213 self.indentation -= indent
214
214
215 @contextmanager
215 @contextmanager
216 def group(self, indent=0, open='', close=''):
216 def group(self, indent=0, open='', close=''):
217 """like begin_group / end_group but for the with statement."""
217 """like begin_group / end_group but for the with statement."""
218 self.begin_group(indent, open)
218 self.begin_group(indent, open)
219 try:
219 try:
220 yield
220 yield
221 finally:
221 finally:
222 self.end_group(indent, close)
222 self.end_group(indent, close)
223
223
224 class PrettyPrinter(_PrettyPrinterBase):
224 class PrettyPrinter(_PrettyPrinterBase):
225 """
225 """
226 Baseclass for the `RepresentationPrinter` prettyprinter that is used to
226 Baseclass for the `RepresentationPrinter` prettyprinter that is used to
227 generate pretty reprs of objects. Contrary to the `RepresentationPrinter`
227 generate pretty reprs of objects. Contrary to the `RepresentationPrinter`
228 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_`
229 callback method.
229 callback method.
230 """
230 """
231
231
232 def __init__(self, output, max_width=79, newline='\n'):
232 def __init__(self, output, max_width=79, newline='\n', max_seq_length=1000):
233 self.output = output
233 self.output = output
234 self.max_width = max_width
234 self.max_width = max_width
235 self.newline = newline
235 self.newline = newline
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 self.max_seq_length and 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 _seq_pprinter_factory(start, end, basetype):
597 def _seq_pprinter_factory(start, end, basetype):
587 """
598 """
588 Factory that returns a pprint function useful for sequences. Used by
599 Factory that returns a pprint function useful for sequences. Used by
589 the default pprint for tuples, dicts, and lists.
600 the default pprint for tuples, dicts, and lists.
590 """
601 """
591 def inner(obj, p, cycle):
602 def inner(obj, p, cycle):
592 typ = type(obj)
603 typ = type(obj)
593 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__:
594 # If the subclass provides its own repr, use it instead.
605 # If the subclass provides its own repr, use it instead.
595 return p.text(typ.__repr__(obj))
606 return p.text(typ.__repr__(obj))
596
607
597 if cycle:
608 if cycle:
598 return p.text(start + '...' + end)
609 return p.text(start + '...' + end)
599 step = len(start)
610 step = len(start)
600 p.begin_group(step, start)
611 p.begin_group(step, start)
601 for idx, x in enumerate(obj):
612 for idx, x in p._enumerate(obj):
602 if idx:
613 if idx:
603 p.text(',')
614 p.text(',')
604 p.breakable()
615 p.breakable()
605 p.pretty(x)
616 p.pretty(x)
606 if len(obj) == 1 and type(obj) is tuple:
617 if len(obj) == 1 and type(obj) is tuple:
607 # Special case for 1-item tuples.
618 # Special case for 1-item tuples.
608 p.text(',')
619 p.text(',')
609 p.end_group(step, end)
620 p.end_group(step, end)
610 return inner
621 return inner
611
622
612
623
613 def _set_pprinter_factory(start, end, basetype):
624 def _set_pprinter_factory(start, end, basetype):
614 """
625 """
615 Factory that returns a pprint function useful for sets and frozensets.
626 Factory that returns a pprint function useful for sets and frozensets.
616 """
627 """
617 def inner(obj, p, cycle):
628 def inner(obj, p, cycle):
618 typ = type(obj)
629 typ = type(obj)
619 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__:
620 # If the subclass provides its own repr, use it instead.
631 # If the subclass provides its own repr, use it instead.
621 return p.text(typ.__repr__(obj))
632 return p.text(typ.__repr__(obj))
622
633
623 if cycle:
634 if cycle:
624 return p.text(start + '...' + end)
635 return p.text(start + '...' + end)
625 if len(obj) == 0:
636 if len(obj) == 0:
626 # Special case.
637 # Special case.
627 p.text(basetype.__name__ + '()')
638 p.text(basetype.__name__ + '()')
628 else:
639 else:
629 step = len(start)
640 step = len(start)
630 p.begin_group(step, start)
641 p.begin_group(step, start)
631 # Like dictionary keys, we will try to sort the items.
642 # Like dictionary keys, we will try to sort the items.
632 items = list(obj)
643 items = list(obj)
633 try:
644 try:
634 items.sort()
645 items.sort()
635 except Exception:
646 except Exception:
636 # Sometimes the items don't sort.
647 # Sometimes the items don't sort.
637 pass
648 pass
638 for idx, x in enumerate(items):
649 for idx, x in p._enumerate(items):
639 if idx:
650 if idx:
640 p.text(',')
651 p.text(',')
641 p.breakable()
652 p.breakable()
642 p.pretty(x)
653 p.pretty(x)
643 p.end_group(step, end)
654 p.end_group(step, end)
644 return inner
655 return inner
645
656
646
657
647 def _dict_pprinter_factory(start, end, basetype=None):
658 def _dict_pprinter_factory(start, end, basetype=None):
648 """
659 """
649 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
650 dicts and dict proxies.
661 dicts and dict proxies.
651 """
662 """
652 def inner(obj, p, cycle):
663 def inner(obj, p, cycle):
653 typ = type(obj)
664 typ = type(obj)
654 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__:
655 # If the subclass provides its own repr, use it instead.
666 # If the subclass provides its own repr, use it instead.
656 return p.text(typ.__repr__(obj))
667 return p.text(typ.__repr__(obj))
657
668
658 if cycle:
669 if cycle:
659 return p.text('{...}')
670 return p.text('{...}')
660 p.begin_group(1, start)
671 p.begin_group(1, start)
661 keys = obj.keys()
672 keys = obj.keys()
662 try:
673 try:
663 keys.sort()
674 keys.sort()
664 except Exception as e:
675 except Exception as e:
665 # Sometimes the keys don't sort.
676 # Sometimes the keys don't sort.
666 pass
677 pass
667 for idx, key in enumerate(keys):
678 for idx, key in p._enumerate(keys):
668 if idx:
679 if idx:
669 p.text(',')
680 p.text(',')
670 p.breakable()
681 p.breakable()
671 p.pretty(key)
682 p.pretty(key)
672 p.text(': ')
683 p.text(': ')
673 p.pretty(obj[key])
684 p.pretty(obj[key])
674 p.end_group(1, end)
685 p.end_group(1, end)
675 return inner
686 return inner
676
687
677
688
678 def _super_pprint(obj, p, cycle):
689 def _super_pprint(obj, p, cycle):
679 """The pprint for the super type."""
690 """The pprint for the super type."""
680 p.begin_group(8, '<super: ')
691 p.begin_group(8, '<super: ')
681 p.pretty(obj.__thisclass__)
692 p.pretty(obj.__thisclass__)
682 p.text(',')
693 p.text(',')
683 p.breakable()
694 p.breakable()
684 p.pretty(obj.__self__)
695 p.pretty(obj.__self__)
685 p.end_group(8, '>')
696 p.end_group(8, '>')
686
697
687
698
688 def _re_pattern_pprint(obj, p, cycle):
699 def _re_pattern_pprint(obj, p, cycle):
689 """The pprint function for regular expression patterns."""
700 """The pprint function for regular expression patterns."""
690 p.text('re.compile(')
701 p.text('re.compile(')
691 pattern = repr(obj.pattern)
702 pattern = repr(obj.pattern)
692 if pattern[:1] in 'uU':
703 if pattern[:1] in 'uU':
693 pattern = pattern[1:]
704 pattern = pattern[1:]
694 prefix = 'ur'
705 prefix = 'ur'
695 else:
706 else:
696 prefix = 'r'
707 prefix = 'r'
697 pattern = prefix + pattern.replace('\\\\', '\\')
708 pattern = prefix + pattern.replace('\\\\', '\\')
698 p.text(pattern)
709 p.text(pattern)
699 if obj.flags:
710 if obj.flags:
700 p.text(',')
711 p.text(',')
701 p.breakable()
712 p.breakable()
702 done_one = False
713 done_one = False
703 for flag in ('TEMPLATE', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL',
714 for flag in ('TEMPLATE', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL',
704 'UNICODE', 'VERBOSE', 'DEBUG'):
715 'UNICODE', 'VERBOSE', 'DEBUG'):
705 if obj.flags & getattr(re, flag):
716 if obj.flags & getattr(re, flag):
706 if done_one:
717 if done_one:
707 p.text('|')
718 p.text('|')
708 p.text('re.' + flag)
719 p.text('re.' + flag)
709 done_one = True
720 done_one = True
710 p.text(')')
721 p.text(')')
711
722
712
723
713 def _type_pprint(obj, p, cycle):
724 def _type_pprint(obj, p, cycle):
714 """The pprint for classes and types."""
725 """The pprint for classes and types."""
715 mod = _safe_getattr(obj, '__module__', None)
726 mod = _safe_getattr(obj, '__module__', None)
716 if mod is None:
727 if mod is None:
717 # Heap allocated types might not have the module attribute,
728 # Heap allocated types might not have the module attribute,
718 # and others may set it to None.
729 # and others may set it to None.
719 return p.text(obj.__name__)
730 return p.text(obj.__name__)
720
731
721 if mod in ('__builtin__', 'builtins', 'exceptions'):
732 if mod in ('__builtin__', 'builtins', 'exceptions'):
722 name = obj.__name__
733 name = obj.__name__
723 else:
734 else:
724 name = mod + '.' + obj.__name__
735 name = mod + '.' + obj.__name__
725 p.text(name)
736 p.text(name)
726
737
727
738
728 def _repr_pprint(obj, p, cycle):
739 def _repr_pprint(obj, p, cycle):
729 """A pprint that just redirects to the normal repr function."""
740 """A pprint that just redirects to the normal repr function."""
730 p.text(_safe_repr(obj))
741 p.text(_safe_repr(obj))
731
742
732
743
733 def _function_pprint(obj, p, cycle):
744 def _function_pprint(obj, p, cycle):
734 """Base pprint for all functions and builtin functions."""
745 """Base pprint for all functions and builtin functions."""
735 if obj.__module__ in ('__builtin__', 'builtins', 'exceptions') or not obj.__module__:
746 if obj.__module__ in ('__builtin__', 'builtins', 'exceptions') or not obj.__module__:
736 name = obj.__name__
747 name = obj.__name__
737 else:
748 else:
738 name = obj.__module__ + '.' + obj.__name__
749 name = obj.__module__ + '.' + obj.__name__
739 p.text('<function %s>' % name)
750 p.text('<function %s>' % name)
740
751
741
752
742 def _exception_pprint(obj, p, cycle):
753 def _exception_pprint(obj, p, cycle):
743 """Base pprint for all exceptions."""
754 """Base pprint for all exceptions."""
744 if obj.__class__.__module__ in ('exceptions', 'builtins'):
755 if obj.__class__.__module__ in ('exceptions', 'builtins'):
745 name = obj.__class__.__name__
756 name = obj.__class__.__name__
746 else:
757 else:
747 name = '%s.%s' % (
758 name = '%s.%s' % (
748 obj.__class__.__module__,
759 obj.__class__.__module__,
749 obj.__class__.__name__
760 obj.__class__.__name__
750 )
761 )
751 step = len(name) + 1
762 step = len(name) + 1
752 p.begin_group(step, name + '(')
763 p.begin_group(step, name + '(')
753 for idx, arg in enumerate(getattr(obj, 'args', ())):
764 for idx, arg in enumerate(getattr(obj, 'args', ())):
754 if idx:
765 if idx:
755 p.text(',')
766 p.text(',')
756 p.breakable()
767 p.breakable()
757 p.pretty(arg)
768 p.pretty(arg)
758 p.end_group(step, ')')
769 p.end_group(step, ')')
759
770
760
771
761 #: the exception base
772 #: the exception base
762 try:
773 try:
763 _exception_base = BaseException
774 _exception_base = BaseException
764 except NameError:
775 except NameError:
765 _exception_base = Exception
776 _exception_base = Exception
766
777
767
778
768 #: printers for builtin types
779 #: printers for builtin types
769 _type_pprinters = {
780 _type_pprinters = {
770 int: _repr_pprint,
781 int: _repr_pprint,
771 float: _repr_pprint,
782 float: _repr_pprint,
772 str: _repr_pprint,
783 str: _repr_pprint,
773 tuple: _seq_pprinter_factory('(', ')', tuple),
784 tuple: _seq_pprinter_factory('(', ')', tuple),
774 list: _seq_pprinter_factory('[', ']', list),
785 list: _seq_pprinter_factory('[', ']', list),
775 dict: _dict_pprinter_factory('{', '}', dict),
786 dict: _dict_pprinter_factory('{', '}', dict),
776
787
777 set: _set_pprinter_factory('{', '}', set),
788 set: _set_pprinter_factory('{', '}', set),
778 frozenset: _set_pprinter_factory('frozenset({', '})', frozenset),
789 frozenset: _set_pprinter_factory('frozenset({', '})', frozenset),
779 super: _super_pprint,
790 super: _super_pprint,
780 _re_pattern_type: _re_pattern_pprint,
791 _re_pattern_type: _re_pattern_pprint,
781 type: _type_pprint,
792 type: _type_pprint,
782 types.FunctionType: _function_pprint,
793 types.FunctionType: _function_pprint,
783 types.BuiltinFunctionType: _function_pprint,
794 types.BuiltinFunctionType: _function_pprint,
784 types.MethodType: _repr_pprint,
795 types.MethodType: _repr_pprint,
785
796
786 datetime.datetime: _repr_pprint,
797 datetime.datetime: _repr_pprint,
787 datetime.timedelta: _repr_pprint,
798 datetime.timedelta: _repr_pprint,
788 _exception_base: _exception_pprint
799 _exception_base: _exception_pprint
789 }
800 }
790
801
791 try:
802 try:
792 _type_pprinters[types.DictProxyType] = _dict_pprinter_factory('<dictproxy {', '}>')
803 _type_pprinters[types.DictProxyType] = _dict_pprinter_factory('<dictproxy {', '}>')
793 _type_pprinters[types.ClassType] = _type_pprint
804 _type_pprinters[types.ClassType] = _type_pprint
794 _type_pprinters[types.SliceType] = _repr_pprint
805 _type_pprinters[types.SliceType] = _repr_pprint
795 except AttributeError: # Python 3
806 except AttributeError: # Python 3
796 _type_pprinters[slice] = _repr_pprint
807 _type_pprinters[slice] = _repr_pprint
797
808
798 try:
809 try:
799 _type_pprinters[xrange] = _repr_pprint
810 _type_pprinters[xrange] = _repr_pprint
800 _type_pprinters[long] = _repr_pprint
811 _type_pprinters[long] = _repr_pprint
801 _type_pprinters[unicode] = _repr_pprint
812 _type_pprinters[unicode] = _repr_pprint
802 except NameError:
813 except NameError:
803 _type_pprinters[range] = _repr_pprint
814 _type_pprinters[range] = _repr_pprint
804 _type_pprinters[bytes] = _repr_pprint
815 _type_pprinters[bytes] = _repr_pprint
805
816
806 #: printers for types specified by name
817 #: printers for types specified by name
807 _deferred_type_pprinters = {
818 _deferred_type_pprinters = {
808 }
819 }
809
820
810 def for_type(typ, func):
821 def for_type(typ, func):
811 """
822 """
812 Add a pretty printer for a given type.
823 Add a pretty printer for a given type.
813 """
824 """
814 oldfunc = _type_pprinters.get(typ, None)
825 oldfunc = _type_pprinters.get(typ, None)
815 if func is not None:
826 if func is not None:
816 # 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.
817 _type_pprinters[typ] = func
828 _type_pprinters[typ] = func
818 return oldfunc
829 return oldfunc
819
830
820 def for_type_by_name(type_module, type_name, func):
831 def for_type_by_name(type_module, type_name, func):
821 """
832 """
822 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
823 rather than the type object itself.
834 rather than the type object itself.
824 """
835 """
825 key = (type_module, type_name)
836 key = (type_module, type_name)
826 oldfunc = _deferred_type_pprinters.get(key, None)
837 oldfunc = _deferred_type_pprinters.get(key, None)
827 if func is not None:
838 if func is not None:
828 # 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.
829 _deferred_type_pprinters[key] = func
840 _deferred_type_pprinters[key] = func
830 return oldfunc
841 return oldfunc
831
842
832
843
833 #: printers for the default singletons
844 #: printers for the default singletons
834 _singleton_pprinters = dict.fromkeys(map(id, [None, True, False, Ellipsis,
845 _singleton_pprinters = dict.fromkeys(map(id, [None, True, False, Ellipsis,
835 NotImplemented]), _repr_pprint)
846 NotImplemented]), _repr_pprint)
836
847
837
848
838 if __name__ == '__main__':
849 if __name__ == '__main__':
839 from random import randrange
850 from random import randrange
840 class Foo(object):
851 class Foo(object):
841 def __init__(self):
852 def __init__(self):
842 self.foo = 1
853 self.foo = 1
843 self.bar = re.compile(r'\s+')
854 self.bar = re.compile(r'\s+')
844 self.blub = dict.fromkeys(range(30), randrange(1, 40))
855 self.blub = dict.fromkeys(range(30), randrange(1, 40))
845 self.hehe = 23424.234234
856 self.hehe = 23424.234234
846 self.list = ["blub", "blah", self]
857 self.list = ["blub", "blah", self]
847
858
848 def get_foo(self):
859 def get_foo(self):
849 print("foo")
860 print("foo")
850
861
851 pprint(Foo(), verbose=True)
862 pprint(Foo(), verbose=True)
@@ -1,199 +1,224 b''
1 """Tests for IPython.lib.pretty.
1 """Tests for IPython.lib.pretty.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2011, the IPython Development Team.
4 # Copyright (c) 2011, the IPython Development Team.
5 #
5 #
6 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
7 #
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 from __future__ import print_function
14 from __future__ import print_function
15
15
16 # Third-party imports
16 # Third-party imports
17 import nose.tools as nt
17 import nose.tools as nt
18
18
19 # Our own imports
19 # Our own imports
20 from IPython.lib import pretty
20 from IPython.lib import pretty
21 from IPython.testing.decorators import skip_without
21 from IPython.testing.decorators import skip_without
22
22
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24 # Classes and functions
24 # Classes and functions
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26
26
27 class MyList(object):
27 class MyList(object):
28 def __init__(self, content):
28 def __init__(self, content):
29 self.content = content
29 self.content = content
30 def _repr_pretty_(self, p, cycle):
30 def _repr_pretty_(self, p, cycle):
31 if cycle:
31 if cycle:
32 p.text("MyList(...)")
32 p.text("MyList(...)")
33 else:
33 else:
34 with p.group(3, "MyList(", ")"):
34 with p.group(3, "MyList(", ")"):
35 for (i, child) in enumerate(self.content):
35 for (i, child) in enumerate(self.content):
36 if i:
36 if i:
37 p.text(",")
37 p.text(",")
38 p.breakable()
38 p.breakable()
39 else:
39 else:
40 p.breakable("")
40 p.breakable("")
41 p.pretty(child)
41 p.pretty(child)
42
42
43
43
44 class MyDict(dict):
44 class MyDict(dict):
45 def _repr_pretty_(self, p, cycle):
45 def _repr_pretty_(self, p, cycle):
46 p.text("MyDict(...)")
46 p.text("MyDict(...)")
47
47
48
48
49 class Dummy1(object):
49 class Dummy1(object):
50 def _repr_pretty_(self, p, cycle):
50 def _repr_pretty_(self, p, cycle):
51 p.text("Dummy1(...)")
51 p.text("Dummy1(...)")
52
52
53 class Dummy2(Dummy1):
53 class Dummy2(Dummy1):
54 _repr_pretty_ = None
54 _repr_pretty_ = None
55
55
56 class NoModule(object):
56 class NoModule(object):
57 pass
57 pass
58
58
59 NoModule.__module__ = None
59 NoModule.__module__ = None
60
60
61 class Breaking(object):
61 class Breaking(object):
62 def _repr_pretty_(self, p, cycle):
62 def _repr_pretty_(self, p, cycle):
63 with p.group(4,"TG: ",":"):
63 with p.group(4,"TG: ",":"):
64 p.text("Breaking(")
64 p.text("Breaking(")
65 p.break_()
65 p.break_()
66 p.text(")")
66 p.text(")")
67
67
68 class BreakingRepr(object):
68 class BreakingRepr(object):
69 def __repr__(self):
69 def __repr__(self):
70 return "Breaking(\n)"
70 return "Breaking(\n)"
71
71
72 class BreakingReprParent(object):
72 class BreakingReprParent(object):
73 def _repr_pretty_(self, p, cycle):
73 def _repr_pretty_(self, p, cycle):
74 with p.group(4,"TG: ",":"):
74 with p.group(4,"TG: ",":"):
75 p.pretty(BreakingRepr())
75 p.pretty(BreakingRepr())
76
76
77 class BadRepr(object):
77 class BadRepr(object):
78
78
79 def __repr__(self):
79 def __repr__(self):
80 return 1/0
80 return 1/0
81
81
82
82
83 def test_indentation():
83 def test_indentation():
84 """Test correct indentation in groups"""
84 """Test correct indentation in groups"""
85 count = 40
85 count = 40
86 gotoutput = pretty.pretty(MyList(range(count)))
86 gotoutput = pretty.pretty(MyList(range(count)))
87 expectedoutput = "MyList(\n" + ",\n".join(" %d" % i for i in range(count)) + ")"
87 expectedoutput = "MyList(\n" + ",\n".join(" %d" % i for i in range(count)) + ")"
88
88
89 nt.assert_equal(gotoutput, expectedoutput)
89 nt.assert_equal(gotoutput, expectedoutput)
90
90
91
91
92 def test_dispatch():
92 def test_dispatch():
93 """
93 """
94 Test correct dispatching: The _repr_pretty_ method for MyDict
94 Test correct dispatching: The _repr_pretty_ method for MyDict
95 must be found before the registered printer for dict.
95 must be found before the registered printer for dict.
96 """
96 """
97 gotoutput = pretty.pretty(MyDict())
97 gotoutput = pretty.pretty(MyDict())
98 expectedoutput = "MyDict(...)"
98 expectedoutput = "MyDict(...)"
99
99
100 nt.assert_equal(gotoutput, expectedoutput)
100 nt.assert_equal(gotoutput, expectedoutput)
101
101
102
102
103 def test_callability_checking():
103 def test_callability_checking():
104 """
104 """
105 Test that the _repr_pretty_ method is tested for callability and skipped if
105 Test that the _repr_pretty_ method is tested for callability and skipped if
106 not.
106 not.
107 """
107 """
108 gotoutput = pretty.pretty(Dummy2())
108 gotoutput = pretty.pretty(Dummy2())
109 expectedoutput = "Dummy1(...)"
109 expectedoutput = "Dummy1(...)"
110
110
111 nt.assert_equal(gotoutput, expectedoutput)
111 nt.assert_equal(gotoutput, expectedoutput)
112
112
113
113
114 def test_sets():
114 def test_sets():
115 """
115 """
116 Test that set and frozenset use Python 3 formatting.
116 Test that set and frozenset use Python 3 formatting.
117 """
117 """
118 objects = [set(), frozenset(), set([1]), frozenset([1]), set([1, 2]),
118 objects = [set(), frozenset(), set([1]), frozenset([1]), set([1, 2]),
119 frozenset([1, 2]), set([-1, -2, -3])]
119 frozenset([1, 2]), set([-1, -2, -3])]
120 expected = ['set()', 'frozenset()', '{1}', 'frozenset({1})', '{1, 2}',
120 expected = ['set()', 'frozenset()', '{1}', 'frozenset({1})', '{1, 2}',
121 'frozenset({1, 2})', '{-3, -2, -1}']
121 'frozenset({1, 2})', '{-3, -2, -1}']
122 for obj, expected_output in zip(objects, expected):
122 for obj, expected_output in zip(objects, expected):
123 got_output = pretty.pretty(obj)
123 got_output = pretty.pretty(obj)
124 yield nt.assert_equal, got_output, expected_output
124 yield nt.assert_equal, got_output, expected_output
125
125
126
126
127 @skip_without('xxlimited')
127 @skip_without('xxlimited')
128 def test_pprint_heap_allocated_type():
128 def test_pprint_heap_allocated_type():
129 """
129 """
130 Test that pprint works for heap allocated types.
130 Test that pprint works for heap allocated types.
131 """
131 """
132 import xxlimited
132 import xxlimited
133 output = pretty.pretty(xxlimited.Null)
133 output = pretty.pretty(xxlimited.Null)
134 nt.assert_equal(output, 'xxlimited.Null')
134 nt.assert_equal(output, 'xxlimited.Null')
135
135
136 def test_pprint_nomod():
136 def test_pprint_nomod():
137 """
137 """
138 Test that pprint works for classes with no __module__.
138 Test that pprint works for classes with no __module__.
139 """
139 """
140 output = pretty.pretty(NoModule)
140 output = pretty.pretty(NoModule)
141 nt.assert_equal(output, 'NoModule')
141 nt.assert_equal(output, 'NoModule')
142
142
143 def test_pprint_break():
143 def test_pprint_break():
144 """
144 """
145 Test that p.break_ produces expected output
145 Test that p.break_ produces expected output
146 """
146 """
147 output = pretty.pretty(Breaking())
147 output = pretty.pretty(Breaking())
148 expected = "TG: Breaking(\n ):"
148 expected = "TG: Breaking(\n ):"
149 nt.assert_equal(output, expected)
149 nt.assert_equal(output, expected)
150
150
151 def test_pprint_break_repr():
151 def test_pprint_break_repr():
152 """
152 """
153 Test that p.break_ is used in repr
153 Test that p.break_ is used in repr
154 """
154 """
155 output = pretty.pretty(BreakingReprParent())
155 output = pretty.pretty(BreakingReprParent())
156 expected = "TG: Breaking(\n ):"
156 expected = "TG: Breaking(\n ):"
157 nt.assert_equal(output, expected)
157 nt.assert_equal(output, expected)
158
158
159 def test_bad_repr():
159 def test_bad_repr():
160 """Don't raise, even when repr fails"""
160 """Don't raise, even when repr fails"""
161 output = pretty.pretty(BadRepr())
161 output = pretty.pretty(BadRepr())
162 nt.assert_in("failed", output)
162 nt.assert_in("failed", output)
163 nt.assert_in("at 0x", output)
163 nt.assert_in("at 0x", output)
164 nt.assert_in("test_pretty", output)
164 nt.assert_in("test_pretty", output)
165
165
166 class BadException(Exception):
166 class BadException(Exception):
167 def __str__(self):
167 def __str__(self):
168 return -1
168 return -1
169
169
170 class ReallyBadRepr(object):
170 class ReallyBadRepr(object):
171 __module__ = 1
171 __module__ = 1
172 @property
172 @property
173 def __class__(self):
173 def __class__(self):
174 raise ValueError("I am horrible")
174 raise ValueError("I am horrible")
175
175
176 def __repr__(self):
176 def __repr__(self):
177 raise BadException()
177 raise BadException()
178
178
179 def test_really_bad_repr():
179 def test_really_bad_repr():
180 output = pretty.pretty(ReallyBadRepr())
180 output = pretty.pretty(ReallyBadRepr())
181 nt.assert_in("failed", output)
181 nt.assert_in("failed", output)
182 nt.assert_in("BadException: unknown", output)
182 nt.assert_in("BadException: unknown", output)
183 nt.assert_in("unknown type", output)
183 nt.assert_in("unknown type", output)
184
184
185
185
186 class SA(object):
186 class SA(object):
187 pass
187 pass
188
188
189 class SB(SA):
189 class SB(SA):
190 pass
190 pass
191
191
192 def test_super_repr():
192 def test_super_repr():
193 output = pretty.pretty(super(SA))
193 output = pretty.pretty(super(SA))
194 nt.assert_in("SA", output)
194 nt.assert_in("SA", output)
195
195
196 sb = SB()
196 sb = SB()
197 output = pretty.pretty(super(SA, sb))
197 output = pretty.pretty(super(SA, sb))
198 nt.assert_in("SA", output)
198 nt.assert_in("SA", output)
199 No newline at end of file
199
200
201 def test_long_list():
202 lis = list(range(10000))
203 p = pretty.pretty(lis)
204 last2 = p.rsplit('\n', 2)[-2:]
205 nt.assert_equal(last2, [' 999,', ' ...]'])
206
207 def test_long_set():
208 s = set(range(10000))
209 p = pretty.pretty(s)
210 last2 = p.rsplit('\n', 2)[-2:]
211 nt.assert_equal(last2, [' 999,', ' ...}'])
212
213 def test_long_tuple():
214 tup = tuple(range(10000))
215 p = pretty.pretty(tup)
216 last2 = p.rsplit('\n', 2)[-2:]
217 nt.assert_equal(last2, [' 999,', ' ...)'])
218
219 def test_long_dict():
220 d = { n:n for n in range(10000) }
221 p = pretty.pretty(d)
222 last2 = p.rsplit('\n', 2)[-2:]
223 nt.assert_equal(last2, [' 999: 999,', ' ...}'])
224
General Comments 0
You need to be logged in to leave comments. Login now