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