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