##// END OF EJS Templates
Fix double indentation in _PrettyPrinterBase.group()....
Walter Doerwald -
Show More
@@ -1,729 +1,728 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 with self.indent(indent):
159 158 yield
160 159 finally:
161 160 self.end_group(indent, close)
162 161
163 162 class PrettyPrinter(_PrettyPrinterBase):
164 163 """
165 164 Baseclass for the `RepresentationPrinter` prettyprinter that is used to
166 165 generate pretty reprs of objects. Contrary to the `RepresentationPrinter`
167 166 this printer knows nothing about the default pprinters or the `_repr_pretty_`
168 167 callback method.
169 168 """
170 169
171 170 def __init__(self, output, max_width=79, newline='\n'):
172 171 self.output = output
173 172 self.max_width = max_width
174 173 self.newline = newline
175 174 self.output_width = 0
176 175 self.buffer_width = 0
177 176 self.buffer = deque()
178 177
179 178 root_group = Group(0)
180 179 self.group_stack = [root_group]
181 180 self.group_queue = GroupQueue(root_group)
182 181 self.indentation = 0
183 182
184 183 def _break_outer_groups(self):
185 184 while self.max_width < self.output_width + self.buffer_width:
186 185 group = self.group_queue.deq()
187 186 if not group:
188 187 return
189 188 while group.breakables:
190 189 x = self.buffer.popleft()
191 190 self.output_width = x.output(self.output, self.output_width)
192 191 self.buffer_width -= x.width
193 192 while self.buffer and isinstance(self.buffer[0], Text):
194 193 x = self.buffer.popleft()
195 194 self.output_width = x.output(self.output, self.output_width)
196 195 self.buffer_width -= x.width
197 196
198 197 def text(self, obj):
199 198 """Add literal text to the output."""
200 199 width = len(obj)
201 200 if self.buffer:
202 201 text = self.buffer[-1]
203 202 if not isinstance(text, Text):
204 203 text = Text()
205 204 self.buffer.append(text)
206 205 text.add(obj, width)
207 206 self.buffer_width += width
208 207 self._break_outer_groups()
209 208 else:
210 209 self.output.write(obj)
211 210 self.output_width += width
212 211
213 212 def breakable(self, sep=' '):
214 213 """
215 214 Add a breakable separator to the output. This does not mean that it
216 215 will automatically break here. If no breaking on this position takes
217 216 place the `sep` is inserted which default to one space.
218 217 """
219 218 width = len(sep)
220 219 group = self.group_stack[-1]
221 220 if group.want_break:
222 221 self.flush()
223 222 self.output.write(self.newline)
224 223 self.output.write(' ' * self.indentation)
225 224 self.output_width = self.indentation
226 225 self.buffer_width = 0
227 226 else:
228 227 self.buffer.append(Breakable(sep, width, self))
229 228 self.buffer_width += width
230 229 self._break_outer_groups()
231 230
232 231
233 232 def begin_group(self, indent=0, open=''):
234 233 """
235 234 Begin a group. If you want support for python < 2.5 which doesn't has
236 235 the with statement this is the preferred way:
237 236
238 237 p.begin_group(1, '{')
239 238 ...
240 239 p.end_group(1, '}')
241 240
242 241 The python 2.5 expression would be this:
243 242
244 243 with p.group(1, '{', '}'):
245 244 ...
246 245
247 246 The first parameter specifies the indentation for the next line (usually
248 247 the width of the opening text), the second the opening text. All
249 248 parameters are optional.
250 249 """
251 250 if open:
252 251 self.text(open)
253 252 group = Group(self.group_stack[-1].depth + 1)
254 253 self.group_stack.append(group)
255 254 self.group_queue.enq(group)
256 255 self.indentation += indent
257 256
258 257 def end_group(self, dedent=0, close=''):
259 258 """End a group. See `begin_group` for more details."""
260 259 self.indentation -= dedent
261 260 group = self.group_stack.pop()
262 261 if not group.breakables:
263 262 self.group_queue.remove(group)
264 263 if close:
265 264 self.text(close)
266 265
267 266 def flush(self):
268 267 """Flush data that is left in the buffer."""
269 268 for data in self.buffer:
270 269 self.output_width += data.output(self.output, self.output_width)
271 270 self.buffer.clear()
272 271 self.buffer_width = 0
273 272
274 273
275 274 def _get_mro(obj_class):
276 275 """ Get a reasonable method resolution order of a class and its superclasses
277 276 for both old-style and new-style classes.
278 277 """
279 278 if not hasattr(obj_class, '__mro__'):
280 279 # Old-style class. Mix in object to make a fake new-style class.
281 280 try:
282 281 obj_class = type(obj_class.__name__, (obj_class, object), {})
283 282 except TypeError:
284 283 # Old-style extension type that does not descend from object.
285 284 # FIXME: try to construct a more thorough MRO.
286 285 mro = [obj_class]
287 286 else:
288 287 mro = obj_class.__mro__[1:-1]
289 288 else:
290 289 mro = obj_class.__mro__
291 290 return mro
292 291
293 292
294 293 class RepresentationPrinter(PrettyPrinter):
295 294 """
296 295 Special pretty printer that has a `pretty` method that calls the pretty
297 296 printer for a python object.
298 297
299 298 This class stores processing data on `self` so you must *never* use
300 299 this class in a threaded environment. Always lock it or reinstanciate
301 300 it.
302 301
303 302 Instances also have a verbose flag callbacks can access to control their
304 303 output. For example the default instance repr prints all attributes and
305 304 methods that are not prefixed by an underscore if the printer is in
306 305 verbose mode.
307 306 """
308 307
309 308 def __init__(self, output, verbose=False, max_width=79, newline='\n',
310 309 singleton_pprinters=None, type_pprinters=None, deferred_pprinters=None):
311 310
312 311 PrettyPrinter.__init__(self, output, max_width, newline)
313 312 self.verbose = verbose
314 313 self.stack = []
315 314 if singleton_pprinters is None:
316 315 singleton_pprinters = _singleton_pprinters.copy()
317 316 self.singleton_pprinters = singleton_pprinters
318 317 if type_pprinters is None:
319 318 type_pprinters = _type_pprinters.copy()
320 319 self.type_pprinters = type_pprinters
321 320 if deferred_pprinters is None:
322 321 deferred_pprinters = _deferred_type_pprinters.copy()
323 322 self.deferred_pprinters = deferred_pprinters
324 323
325 324 def pretty(self, obj):
326 325 """Pretty print the given object."""
327 326 obj_id = id(obj)
328 327 cycle = obj_id in self.stack
329 328 self.stack.append(obj_id)
330 329 self.begin_group()
331 330 try:
332 331 obj_class = getattr(obj, '__class__', None) or type(obj)
333 332 # First try to find registered singleton printers for the type.
334 333 try:
335 334 printer = self.singleton_pprinters[obj_id]
336 335 except (TypeError, KeyError):
337 336 pass
338 337 else:
339 338 return printer(obj, self, cycle)
340 339 # Next look for type_printers.
341 340 for cls in _get_mro(obj_class):
342 341 if cls in self.type_pprinters:
343 342 return self.type_pprinters[cls](obj, self, cycle)
344 343 else:
345 344 printer = self._in_deferred_types(cls)
346 345 if printer is not None:
347 346 return printer(obj, self, cycle)
348 347 # Finally look for special method names.
349 348 if hasattr(obj_class, '_repr_pretty_'):
350 349 # Some objects automatically create any requested
351 350 # attribute. Try to ignore most of them by checking for
352 351 # callability.
353 352 if callable(obj_class._repr_pretty_):
354 353 return obj_class._repr_pretty_(obj, self, cycle)
355 354 return _default_pprint(obj, self, cycle)
356 355 finally:
357 356 self.end_group()
358 357 self.stack.pop()
359 358
360 359 def _in_deferred_types(self, cls):
361 360 """
362 361 Check if the given class is specified in the deferred type registry.
363 362
364 363 Returns the printer from the registry if it exists, and None if the
365 364 class is not in the registry. Successful matches will be moved to the
366 365 regular type registry for future use.
367 366 """
368 367 mod = getattr(cls, '__module__', None)
369 368 name = getattr(cls, '__name__', None)
370 369 key = (mod, name)
371 370 printer = None
372 371 if key in self.deferred_pprinters:
373 372 # Move the printer over to the regular registry.
374 373 printer = self.deferred_pprinters.pop(key)
375 374 self.type_pprinters[cls] = printer
376 375 return printer
377 376
378 377
379 378 class Printable(object):
380 379
381 380 def output(self, stream, output_width):
382 381 return output_width
383 382
384 383
385 384 class Text(Printable):
386 385
387 386 def __init__(self):
388 387 self.objs = []
389 388 self.width = 0
390 389
391 390 def output(self, stream, output_width):
392 391 for obj in self.objs:
393 392 stream.write(obj)
394 393 return output_width + self.width
395 394
396 395 def add(self, obj, width):
397 396 self.objs.append(obj)
398 397 self.width += width
399 398
400 399
401 400 class Breakable(Printable):
402 401
403 402 def __init__(self, seq, width, pretty):
404 403 self.obj = seq
405 404 self.width = width
406 405 self.pretty = pretty
407 406 self.indentation = pretty.indentation
408 407 self.group = pretty.group_stack[-1]
409 408 self.group.breakables.append(self)
410 409
411 410 def output(self, stream, output_width):
412 411 self.group.breakables.popleft()
413 412 if self.group.want_break:
414 413 stream.write(self.pretty.newline)
415 414 stream.write(' ' * self.indentation)
416 415 return self.indentation
417 416 if not self.group.breakables:
418 417 self.pretty.group_queue.remove(self.group)
419 418 stream.write(self.obj)
420 419 return output_width + self.width
421 420
422 421
423 422 class Group(Printable):
424 423
425 424 def __init__(self, depth):
426 425 self.depth = depth
427 426 self.breakables = deque()
428 427 self.want_break = False
429 428
430 429
431 430 class GroupQueue(object):
432 431
433 432 def __init__(self, *groups):
434 433 self.queue = []
435 434 for group in groups:
436 435 self.enq(group)
437 436
438 437 def enq(self, group):
439 438 depth = group.depth
440 439 while depth > len(self.queue) - 1:
441 440 self.queue.append([])
442 441 self.queue[depth].append(group)
443 442
444 443 def deq(self):
445 444 for stack in self.queue:
446 445 for idx, group in enumerate(reversed(stack)):
447 446 if group.breakables:
448 447 del stack[idx]
449 448 group.want_break = True
450 449 return group
451 450 for group in stack:
452 451 group.want_break = True
453 452 del stack[:]
454 453
455 454 def remove(self, group):
456 455 try:
457 456 self.queue[group.depth].remove(group)
458 457 except ValueError:
459 458 pass
460 459
461 460 try:
462 461 _baseclass_reprs = (object.__repr__, types.InstanceType.__repr__)
463 462 except AttributeError: # Python 3
464 463 _baseclass_reprs = (object.__repr__,)
465 464
466 465
467 466 def _default_pprint(obj, p, cycle):
468 467 """
469 468 The default print function. Used if an object does not provide one and
470 469 it's none of the builtin objects.
471 470 """
472 471 klass = getattr(obj, '__class__', None) or type(obj)
473 472 if getattr(klass, '__repr__', None) not in _baseclass_reprs:
474 473 # A user-provided repr.
475 474 p.text(repr(obj))
476 475 return
477 476 p.begin_group(1, '<')
478 477 p.pretty(klass)
479 478 p.text(' at 0x%x' % id(obj))
480 479 if cycle:
481 480 p.text(' ...')
482 481 elif p.verbose:
483 482 first = True
484 483 for key in dir(obj):
485 484 if not key.startswith('_'):
486 485 try:
487 486 value = getattr(obj, key)
488 487 except AttributeError:
489 488 continue
490 489 if isinstance(value, types.MethodType):
491 490 continue
492 491 if not first:
493 492 p.text(',')
494 493 p.breakable()
495 494 p.text(key)
496 495 p.text('=')
497 496 step = len(key) + 1
498 497 p.indentation += step
499 498 p.pretty(value)
500 499 p.indentation -= step
501 500 first = False
502 501 p.end_group(1, '>')
503 502
504 503
505 504 def _seq_pprinter_factory(start, end, basetype):
506 505 """
507 506 Factory that returns a pprint function useful for sequences. Used by
508 507 the default pprint for tuples, dicts, lists, sets and frozensets.
509 508 """
510 509 def inner(obj, p, cycle):
511 510 typ = type(obj)
512 511 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
513 512 # If the subclass provides its own repr, use it instead.
514 513 return p.text(typ.__repr__(obj))
515 514
516 515 if cycle:
517 516 return p.text(start + '...' + end)
518 517 step = len(start)
519 518 p.begin_group(step, start)
520 519 for idx, x in enumerate(obj):
521 520 if idx:
522 521 p.text(',')
523 522 p.breakable()
524 523 p.pretty(x)
525 524 if len(obj) == 1 and type(obj) is tuple:
526 525 # Special case for 1-item tuples.
527 526 p.text(',')
528 527 p.end_group(step, end)
529 528 return inner
530 529
531 530
532 531 def _dict_pprinter_factory(start, end, basetype=None):
533 532 """
534 533 Factory that returns a pprint function used by the default pprint of
535 534 dicts and dict proxies.
536 535 """
537 536 def inner(obj, p, cycle):
538 537 typ = type(obj)
539 538 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
540 539 # If the subclass provides its own repr, use it instead.
541 540 return p.text(typ.__repr__(obj))
542 541
543 542 if cycle:
544 543 return p.text('{...}')
545 544 p.begin_group(1, start)
546 545 keys = obj.keys()
547 546 try:
548 547 keys.sort()
549 548 except Exception, e:
550 549 # Sometimes the keys don't sort.
551 550 pass
552 551 for idx, key in enumerate(keys):
553 552 if idx:
554 553 p.text(',')
555 554 p.breakable()
556 555 p.pretty(key)
557 556 p.text(': ')
558 557 p.pretty(obj[key])
559 558 p.end_group(1, end)
560 559 return inner
561 560
562 561
563 562 def _super_pprint(obj, p, cycle):
564 563 """The pprint for the super type."""
565 564 p.begin_group(8, '<super: ')
566 565 p.pretty(obj.__self_class__)
567 566 p.text(',')
568 567 p.breakable()
569 568 p.pretty(obj.__self__)
570 569 p.end_group(8, '>')
571 570
572 571
573 572 def _re_pattern_pprint(obj, p, cycle):
574 573 """The pprint function for regular expression patterns."""
575 574 p.text('re.compile(')
576 575 pattern = repr(obj.pattern)
577 576 if pattern[:1] in 'uU':
578 577 pattern = pattern[1:]
579 578 prefix = 'ur'
580 579 else:
581 580 prefix = 'r'
582 581 pattern = prefix + pattern.replace('\\\\', '\\')
583 582 p.text(pattern)
584 583 if obj.flags:
585 584 p.text(',')
586 585 p.breakable()
587 586 done_one = False
588 587 for flag in ('TEMPLATE', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL',
589 588 'UNICODE', 'VERBOSE', 'DEBUG'):
590 589 if obj.flags & getattr(re, flag):
591 590 if done_one:
592 591 p.text('|')
593 592 p.text('re.' + flag)
594 593 done_one = True
595 594 p.text(')')
596 595
597 596
598 597 def _type_pprint(obj, p, cycle):
599 598 """The pprint for classes and types."""
600 599 if obj.__module__ in ('__builtin__', 'exceptions'):
601 600 name = obj.__name__
602 601 else:
603 602 name = obj.__module__ + '.' + obj.__name__
604 603 p.text(name)
605 604
606 605
607 606 def _repr_pprint(obj, p, cycle):
608 607 """A pprint that just redirects to the normal repr function."""
609 608 p.text(repr(obj))
610 609
611 610
612 611 def _function_pprint(obj, p, cycle):
613 612 """Base pprint for all functions and builtin functions."""
614 613 if obj.__module__ in ('__builtin__', 'exceptions') or not obj.__module__:
615 614 name = obj.__name__
616 615 else:
617 616 name = obj.__module__ + '.' + obj.__name__
618 617 p.text('<function %s>' % name)
619 618
620 619
621 620 def _exception_pprint(obj, p, cycle):
622 621 """Base pprint for all exceptions."""
623 622 if obj.__class__.__module__ == 'exceptions':
624 623 name = obj.__class__.__name__
625 624 else:
626 625 name = '%s.%s' % (
627 626 obj.__class__.__module__,
628 627 obj.__class__.__name__
629 628 )
630 629 step = len(name) + 1
631 630 p.begin_group(step, '(')
632 631 for idx, arg in enumerate(getattr(obj, 'args', ())):
633 632 if idx:
634 633 p.text(',')
635 634 p.breakable()
636 635 p.pretty(arg)
637 636 p.end_group(step, ')')
638 637
639 638
640 639 #: the exception base
641 640 try:
642 641 _exception_base = BaseException
643 642 except NameError:
644 643 _exception_base = Exception
645 644
646 645
647 646 #: printers for builtin types
648 647 _type_pprinters = {
649 648 int: _repr_pprint,
650 649 long: _repr_pprint,
651 650 float: _repr_pprint,
652 651 str: _repr_pprint,
653 652 unicode: _repr_pprint,
654 653 tuple: _seq_pprinter_factory('(', ')', tuple),
655 654 list: _seq_pprinter_factory('[', ']', list),
656 655 dict: _dict_pprinter_factory('{', '}', dict),
657 656
658 657 set: _seq_pprinter_factory('set([', '])', set),
659 658 frozenset: _seq_pprinter_factory('frozenset([', '])', frozenset),
660 659 super: _super_pprint,
661 660 _re_pattern_type: _re_pattern_pprint,
662 661 type: _type_pprint,
663 662 types.FunctionType: _function_pprint,
664 663 types.BuiltinFunctionType: _function_pprint,
665 664 types.SliceType: _repr_pprint,
666 665 types.MethodType: _repr_pprint,
667 666
668 667 datetime.datetime: _repr_pprint,
669 668 datetime.timedelta: _repr_pprint,
670 669 _exception_base: _exception_pprint
671 670 }
672 671
673 672 try:
674 673 _type_pprinters[types.DictProxyType] = _dict_pprinter_factory('<dictproxy {', '}>')
675 674 _type_pprinters[types.ClassType] = _type_pprint
676 675 except AttributeError: # Python 3
677 676 pass
678 677
679 678 try:
680 679 _type_pprinters[xrange] = _repr_pprint
681 680 except NameError:
682 681 _type_pprinters[range] = _repr_pprint
683 682
684 683 #: printers for types specified by name
685 684 _deferred_type_pprinters = {
686 685 }
687 686
688 687 def for_type(typ, func):
689 688 """
690 689 Add a pretty printer for a given type.
691 690 """
692 691 oldfunc = _type_pprinters.get(typ, None)
693 692 if func is not None:
694 693 # To support easy restoration of old pprinters, we need to ignore Nones.
695 694 _type_pprinters[typ] = func
696 695 return oldfunc
697 696
698 697 def for_type_by_name(type_module, type_name, func):
699 698 """
700 699 Add a pretty printer for a type specified by the module and name of a type
701 700 rather than the type object itself.
702 701 """
703 702 key = (type_module, type_name)
704 703 oldfunc = _deferred_type_pprinters.get(key, None)
705 704 if func is not None:
706 705 # To support easy restoration of old pprinters, we need to ignore Nones.
707 706 _deferred_type_pprinters[key] = func
708 707 return oldfunc
709 708
710 709
711 710 #: printers for the default singletons
712 711 _singleton_pprinters = dict.fromkeys(map(id, [None, True, False, Ellipsis,
713 712 NotImplemented]), _repr_pprint)
714 713
715 714
716 715 if __name__ == '__main__':
717 716 from random import randrange
718 717 class Foo(object):
719 718 def __init__(self):
720 719 self.foo = 1
721 720 self.bar = re.compile(r'\s+')
722 721 self.blub = dict.fromkeys(range(30), randrange(1, 40))
723 722 self.hehe = 23424.234234
724 723 self.list = ["blub", "blah", self]
725 724
726 725 def get_foo(self):
727 726 print "foo"
728 727
729 728 pprint(Foo(), verbose=True)
General Comments 0
You need to be logged in to leave comments. Login now