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