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