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