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