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