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