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