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