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