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