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