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