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