##// END OF EJS Templates
BUG: For subclasses of tuple, list, dict, set, and frozenset, only use the pretty-printer if the subclasses do not replace the base class's __repr__.
Robert Kern -
Show More
@@ -1,700 +1,710 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 `__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 __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 `__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 __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 __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 `__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 if hasattr(obj_class, '__pretty__'):
334 334 return obj_class.__pretty__(obj, self, cycle)
335 335 try:
336 336 printer = self.singleton_pprinters[obj_id]
337 337 except (TypeError, KeyError):
338 338 pass
339 339 else:
340 340 return printer(obj, self, cycle)
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 return _default_pprint(obj, self, cycle)
349 349 finally:
350 350 self.end_group()
351 351 self.stack.pop()
352 352
353 353 def _in_deferred_types(self, cls):
354 354 """
355 355 Check if the given class is specified in the deferred type registry.
356 356
357 357 Returns the printer from the registry if it exists, and None if the
358 358 class is not in the registry. Successful matches will be moved to the
359 359 regular type registry for future use.
360 360 """
361 361 mod = getattr(cls, '__module__', None)
362 362 name = getattr(cls, '__name__', None)
363 363 key = (mod, name)
364 364 printer = None
365 365 if key in self.deferred_pprinters:
366 366 # Move the printer over to the regular registry.
367 367 printer = self.deferred_pprinters.pop(key)
368 368 self.type_pprinters[cls] = printer
369 369 return printer
370 370
371 371
372 372 class Printable(object):
373 373
374 374 def output(self, stream, output_width):
375 375 return output_width
376 376
377 377
378 378 class Text(Printable):
379 379
380 380 def __init__(self):
381 381 self.objs = []
382 382 self.width = 0
383 383
384 384 def output(self, stream, output_width):
385 385 for obj in self.objs:
386 386 stream.write(obj)
387 387 return output_width + self.width
388 388
389 389 def add(self, obj, width):
390 390 self.objs.append(obj)
391 391 self.width += width
392 392
393 393
394 394 class Breakable(Printable):
395 395
396 396 def __init__(self, seq, width, pretty):
397 397 self.obj = seq
398 398 self.width = width
399 399 self.pretty = pretty
400 400 self.indentation = pretty.indentation
401 401 self.group = pretty.group_stack[-1]
402 402 self.group.breakables.append(self)
403 403
404 404 def output(self, stream, output_width):
405 405 self.group.breakables.popleft()
406 406 if self.group.want_break:
407 407 stream.write(self.pretty.newline)
408 408 stream.write(' ' * self.indentation)
409 409 return self.indentation
410 410 if not self.group.breakables:
411 411 self.pretty.group_queue.remove(self.group)
412 412 stream.write(self.obj)
413 413 return output_width + self.width
414 414
415 415
416 416 class Group(Printable):
417 417
418 418 def __init__(self, depth):
419 419 self.depth = depth
420 420 self.breakables = deque()
421 421 self.want_break = False
422 422
423 423
424 424 class GroupQueue(object):
425 425
426 426 def __init__(self, *groups):
427 427 self.queue = []
428 428 for group in groups:
429 429 self.enq(group)
430 430
431 431 def enq(self, group):
432 432 depth = group.depth
433 433 while depth > len(self.queue) - 1:
434 434 self.queue.append([])
435 435 self.queue[depth].append(group)
436 436
437 437 def deq(self):
438 438 for stack in self.queue:
439 439 for idx, group in enumerate(reversed(stack)):
440 440 if group.breakables:
441 441 del stack[idx]
442 442 group.want_break = True
443 443 return group
444 444 for group in stack:
445 445 group.want_break = True
446 446 del stack[:]
447 447
448 448 def remove(self, group):
449 449 try:
450 450 self.queue[group.depth].remove(group)
451 451 except ValueError:
452 452 pass
453 453
454 454
455 455 _baseclass_reprs = (object.__repr__, types.InstanceType.__repr__)
456 456
457 457
458 458 def _default_pprint(obj, p, cycle):
459 459 """
460 460 The default print function. Used if an object does not provide one and
461 461 it's none of the builtin objects.
462 462 """
463 463 klass = getattr(obj, '__class__', None) or type(obj)
464 464 if getattr(klass, '__repr__', None) not in _baseclass_reprs:
465 465 # A user-provided repr.
466 466 p.text(repr(obj))
467 467 return
468 468 p.begin_group(1, '<')
469 469 p.pretty(klass)
470 470 p.text(' at 0x%x' % id(obj))
471 471 if cycle:
472 472 p.text(' ...')
473 473 elif p.verbose:
474 474 first = True
475 475 for key in dir(obj):
476 476 if not key.startswith('_'):
477 477 try:
478 478 value = getattr(obj, key)
479 479 except AttributeError:
480 480 continue
481 481 if isinstance(value, types.MethodType):
482 482 continue
483 483 if not first:
484 484 p.text(',')
485 485 p.breakable()
486 486 p.text(key)
487 487 p.text('=')
488 488 step = len(key) + 1
489 489 p.indentation += step
490 490 p.pretty(value)
491 491 p.indentation -= step
492 492 first = False
493 493 p.end_group(1, '>')
494 494
495 495
496 def _seq_pprinter_factory(start, end):
496 def _seq_pprinter_factory(start, end, basetype):
497 497 """
498 498 Factory that returns a pprint function useful for sequences. Used by
499 499 the default pprint for tuples, dicts, lists, sets and frozensets.
500 500 """
501 501 def inner(obj, p, cycle):
502 typ = type(obj)
503 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
504 # If the subclass provides its own repr, use it instead.
505 return p.text(typ.__repr__(obj))
506
502 507 if cycle:
503 508 return p.text(start + '...' + end)
504 509 step = len(start)
505 510 p.begin_group(step, start)
506 511 for idx, x in enumerate(obj):
507 512 if idx:
508 513 p.text(',')
509 514 p.breakable()
510 515 p.pretty(x)
511 516 if len(obj) == 1 and type(obj) is tuple:
512 517 # Special case for 1-item tuples.
513 518 p.text(',')
514 519 p.end_group(step, end)
515 520 return inner
516 521
517 522
518 def _dict_pprinter_factory(start, end):
523 def _dict_pprinter_factory(start, end, basetype=None):
519 524 """
520 525 Factory that returns a pprint function used by the default pprint of
521 526 dicts and dict proxies.
522 527 """
523 528 def inner(obj, p, cycle):
529 typ = type(obj)
530 if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
531 # If the subclass provides its own repr, use it instead.
532 return p.text(typ.__repr__(obj))
533
524 534 if cycle:
525 535 return p.text('{...}')
526 536 p.begin_group(1, start)
527 537 keys = obj.keys()
528 538 try:
529 539 keys.sort()
530 540 except Exception, e:
531 541 # Sometimes the keys don't sort.
532 542 pass
533 543 for idx, key in enumerate(keys):
534 544 if idx:
535 545 p.text(',')
536 546 p.breakable()
537 547 p.pretty(key)
538 548 p.text(': ')
539 549 p.pretty(obj[key])
540 550 p.end_group(1, end)
541 551 return inner
542 552
543 553
544 554 def _super_pprint(obj, p, cycle):
545 555 """The pprint for the super type."""
546 556 p.begin_group(8, '<super: ')
547 557 p.pretty(obj.__self_class__)
548 558 p.text(',')
549 559 p.breakable()
550 560 p.pretty(obj.__self__)
551 561 p.end_group(8, '>')
552 562
553 563
554 564 def _re_pattern_pprint(obj, p, cycle):
555 565 """The pprint function for regular expression patterns."""
556 566 p.text('re.compile(')
557 567 pattern = repr(obj.pattern)
558 568 if pattern[:1] in 'uU':
559 569 pattern = pattern[1:]
560 570 prefix = 'ur'
561 571 else:
562 572 prefix = 'r'
563 573 pattern = prefix + pattern.replace('\\\\', '\\')
564 574 p.text(pattern)
565 575 if obj.flags:
566 576 p.text(',')
567 577 p.breakable()
568 578 done_one = False
569 579 for flag in ('TEMPLATE', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL',
570 580 'UNICODE', 'VERBOSE', 'DEBUG'):
571 581 if obj.flags & getattr(re, flag):
572 582 if done_one:
573 583 p.text('|')
574 584 p.text('re.' + flag)
575 585 done_one = True
576 586 p.text(')')
577 587
578 588
579 589 def _type_pprint(obj, p, cycle):
580 590 """The pprint for classes and types."""
581 591 if obj.__module__ in ('__builtin__', 'exceptions'):
582 592 name = obj.__name__
583 593 else:
584 594 name = obj.__module__ + '.' + obj.__name__
585 595 p.text(name)
586 596
587 597
588 598 def _repr_pprint(obj, p, cycle):
589 599 """A pprint that just redirects to the normal repr function."""
590 600 p.text(repr(obj))
591 601
592 602
593 603 def _function_pprint(obj, p, cycle):
594 604 """Base pprint for all functions and builtin functions."""
595 605 if obj.__module__ in ('__builtin__', 'exceptions') or not obj.__module__:
596 606 name = obj.__name__
597 607 else:
598 608 name = obj.__module__ + '.' + obj.__name__
599 609 p.text('<function %s>' % name)
600 610
601 611
602 612 def _exception_pprint(obj, p, cycle):
603 613 """Base pprint for all exceptions."""
604 614 if obj.__class__.__module__ == 'exceptions':
605 615 name = obj.__class__.__name__
606 616 else:
607 617 name = '%s.%s' % (
608 618 obj.__class__.__module__,
609 619 obj.__class__.__name__
610 620 )
611 621 step = len(name) + 1
612 622 p.begin_group(step, '(')
613 623 for idx, arg in enumerate(getattr(obj, 'args', ())):
614 624 if idx:
615 625 p.text(',')
616 626 p.breakable()
617 627 p.pretty(arg)
618 628 p.end_group(step, ')')
619 629
620 630
621 631 #: the exception base
622 632 try:
623 633 _exception_base = BaseException
624 634 except NameError:
625 635 _exception_base = Exception
626 636
627 637
628 638 #: printers for builtin types
629 639 _type_pprinters = {
630 640 int: _repr_pprint,
631 641 long: _repr_pprint,
632 642 float: _repr_pprint,
633 643 str: _repr_pprint,
634 644 unicode: _repr_pprint,
635 tuple: _seq_pprinter_factory('(', ')'),
636 list: _seq_pprinter_factory('[', ']'),
637 dict: _dict_pprinter_factory('{', '}'),
645 tuple: _seq_pprinter_factory('(', ')', tuple),
646 list: _seq_pprinter_factory('[', ']', list),
647 dict: _dict_pprinter_factory('{', '}', dict),
638 648 types.DictProxyType: _dict_pprinter_factory('<dictproxy {', '}>'),
639 set: _seq_pprinter_factory('set([', '])'),
640 frozenset: _seq_pprinter_factory('frozenset([', '])'),
649 set: _seq_pprinter_factory('set([', '])', set),
650 frozenset: _seq_pprinter_factory('frozenset([', '])', frozenset),
641 651 super: _super_pprint,
642 652 _re_pattern_type: _re_pattern_pprint,
643 653 type: _type_pprint,
644 654 types.ClassType: _type_pprint,
645 655 types.FunctionType: _function_pprint,
646 656 types.BuiltinFunctionType: _function_pprint,
647 657 types.SliceType: _repr_pprint,
648 658 types.MethodType: _repr_pprint,
649 659 xrange: _repr_pprint,
650 660 datetime.datetime: _repr_pprint,
651 661 datetime.timedelta: _repr_pprint,
652 662 _exception_base: _exception_pprint
653 663 }
654 664
655 665 #: printers for types specified by name
656 666 _deferred_type_pprinters = {
657 667 }
658 668
659 669 def for_type(typ, func):
660 670 """
661 671 Add a pretty printer for a given type.
662 672 """
663 673 oldfunc = _type_pprinters.get(typ, None)
664 674 if func is not None:
665 675 # To support easy restoration of old pprinters, we need to ignore Nones.
666 676 _type_pprinters[typ] = func
667 677 return oldfunc
668 678
669 679 def for_type_by_name(type_module, type_name, func):
670 680 """
671 681 Add a pretty printer for a type specified by the module and name of a type
672 682 rather than the type object itself.
673 683 """
674 684 key = (type_module, type_name)
675 685 oldfunc = _deferred_type_pprinters.get(key, None)
676 686 if func is not None:
677 687 # To support easy restoration of old pprinters, we need to ignore Nones.
678 688 _deferred_type_pprinters[key] = func
679 689 return oldfunc
680 690
681 691
682 692 #: printers for the default singletons
683 693 _singleton_pprinters = dict.fromkeys(map(id, [None, True, False, Ellipsis,
684 694 NotImplemented]), _repr_pprint)
685 695
686 696
687 697 if __name__ == '__main__':
688 698 from random import randrange
689 699 class Foo(object):
690 700 def __init__(self):
691 701 self.foo = 1
692 702 self.bar = re.compile(r'\s+')
693 703 self.blub = dict.fromkeys(range(30), randrange(1, 40))
694 704 self.hehe = 23424.234234
695 705 self.list = ["blub", "blah", self]
696 706
697 707 def get_foo(self):
698 708 print "foo"
699 709
700 710 pprint(Foo(), verbose=True)
General Comments 0
You need to be logged in to leave comments. Login now