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