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