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