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