symbian-qemu-0.9.1-12/python-win32-2.6.1/lib/pprint.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 #  Author:      Fred L. Drake, Jr.
       
     2 #               fdrake@acm.org
       
     3 #
       
     4 #  This is a simple little module I wrote to make life easier.  I didn't
       
     5 #  see anything quite like it in the library, though I may have overlooked
       
     6 #  something.  I wrote this when I was trying to read some heavily nested
       
     7 #  tuples with fairly non-descriptive content.  This is modeled very much
       
     8 #  after Lisp/Scheme - style pretty-printing of lists.  If you find it
       
     9 #  useful, thank small children who sleep at night.
       
    10 
       
    11 """Support to pretty-print lists, tuples, & dictionaries recursively.
       
    12 
       
    13 Very simple, but useful, especially in debugging data structures.
       
    14 
       
    15 Classes
       
    16 -------
       
    17 
       
    18 PrettyPrinter()
       
    19     Handle pretty-printing operations onto a stream using a configured
       
    20     set of formatting parameters.
       
    21 
       
    22 Functions
       
    23 ---------
       
    24 
       
    25 pformat()
       
    26     Format a Python object into a pretty-printed representation.
       
    27 
       
    28 pprint()
       
    29     Pretty-print a Python object to a stream [default is sys.stdout].
       
    30 
       
    31 saferepr()
       
    32     Generate a 'standard' repr()-like value, but protect against recursive
       
    33     data structures.
       
    34 
       
    35 """
       
    36 
       
    37 import sys as _sys
       
    38 
       
    39 from cStringIO import StringIO as _StringIO
       
    40 
       
    41 __all__ = ["pprint","pformat","isreadable","isrecursive","saferepr",
       
    42            "PrettyPrinter"]
       
    43 
       
    44 # cache these for faster access:
       
    45 _commajoin = ", ".join
       
    46 _id = id
       
    47 _len = len
       
    48 _type = type
       
    49 
       
    50 
       
    51 def pprint(object, stream=None, indent=1, width=80, depth=None):
       
    52     """Pretty-print a Python object to a stream [default is sys.stdout]."""
       
    53     printer = PrettyPrinter(
       
    54         stream=stream, indent=indent, width=width, depth=depth)
       
    55     printer.pprint(object)
       
    56 
       
    57 def pformat(object, indent=1, width=80, depth=None):
       
    58     """Format a Python object into a pretty-printed representation."""
       
    59     return PrettyPrinter(indent=indent, width=width, depth=depth).pformat(object)
       
    60 
       
    61 def saferepr(object):
       
    62     """Version of repr() which can handle recursive data structures."""
       
    63     return _safe_repr(object, {}, None, 0)[0]
       
    64 
       
    65 def isreadable(object):
       
    66     """Determine if saferepr(object) is readable by eval()."""
       
    67     return _safe_repr(object, {}, None, 0)[1]
       
    68 
       
    69 def isrecursive(object):
       
    70     """Determine if object requires a recursive representation."""
       
    71     return _safe_repr(object, {}, None, 0)[2]
       
    72 
       
    73 class PrettyPrinter:
       
    74     def __init__(self, indent=1, width=80, depth=None, stream=None):
       
    75         """Handle pretty printing operations onto a stream using a set of
       
    76         configured parameters.
       
    77 
       
    78         indent
       
    79             Number of spaces to indent for each level of nesting.
       
    80 
       
    81         width
       
    82             Attempted maximum number of columns in the output.
       
    83 
       
    84         depth
       
    85             The maximum depth to print out nested structures.
       
    86 
       
    87         stream
       
    88             The desired output stream.  If omitted (or false), the standard
       
    89             output stream available at construction will be used.
       
    90 
       
    91         """
       
    92         indent = int(indent)
       
    93         width = int(width)
       
    94         assert indent >= 0, "indent must be >= 0"
       
    95         assert depth is None or depth > 0, "depth must be > 0"
       
    96         assert width, "width must be != 0"
       
    97         self._depth = depth
       
    98         self._indent_per_level = indent
       
    99         self._width = width
       
   100         if stream is not None:
       
   101             self._stream = stream
       
   102         else:
       
   103             self._stream = _sys.stdout
       
   104 
       
   105     def pprint(self, object):
       
   106         self._format(object, self._stream, 0, 0, {}, 0)
       
   107         self._stream.write("\n")
       
   108 
       
   109     def pformat(self, object):
       
   110         sio = _StringIO()
       
   111         self._format(object, sio, 0, 0, {}, 0)
       
   112         return sio.getvalue()
       
   113 
       
   114     def isrecursive(self, object):
       
   115         return self.format(object, {}, 0, 0)[2]
       
   116 
       
   117     def isreadable(self, object):
       
   118         s, readable, recursive = self.format(object, {}, 0, 0)
       
   119         return readable and not recursive
       
   120 
       
   121     def _format(self, object, stream, indent, allowance, context, level):
       
   122         level = level + 1
       
   123         objid = _id(object)
       
   124         if objid in context:
       
   125             stream.write(_recursion(object))
       
   126             self._recursive = True
       
   127             self._readable = False
       
   128             return
       
   129         rep = self._repr(object, context, level - 1)
       
   130         typ = _type(object)
       
   131         sepLines = _len(rep) > (self._width - 1 - indent - allowance)
       
   132         write = stream.write
       
   133 
       
   134         if self._depth and level > self._depth:
       
   135             write(rep)
       
   136             return
       
   137 
       
   138         r = getattr(typ, "__repr__", None)
       
   139         if issubclass(typ, dict) and r is dict.__repr__:
       
   140             write('{')
       
   141             if self._indent_per_level > 1:
       
   142                 write((self._indent_per_level - 1) * ' ')
       
   143             length = _len(object)
       
   144             if length:
       
   145                 context[objid] = 1
       
   146                 indent = indent + self._indent_per_level
       
   147                 items  = object.items()
       
   148                 items.sort()
       
   149                 key, ent = items[0]
       
   150                 rep = self._repr(key, context, level)
       
   151                 write(rep)
       
   152                 write(': ')
       
   153                 self._format(ent, stream, indent + _len(rep) + 2,
       
   154                               allowance + 1, context, level)
       
   155                 if length > 1:
       
   156                     for key, ent in items[1:]:
       
   157                         rep = self._repr(key, context, level)
       
   158                         if sepLines:
       
   159                             write(',\n%s%s: ' % (' '*indent, rep))
       
   160                         else:
       
   161                             write(', %s: ' % rep)
       
   162                         self._format(ent, stream, indent + _len(rep) + 2,
       
   163                                       allowance + 1, context, level)
       
   164                 indent = indent - self._indent_per_level
       
   165                 del context[objid]
       
   166             write('}')
       
   167             return
       
   168 
       
   169         if ((issubclass(typ, list) and r is list.__repr__) or
       
   170             (issubclass(typ, tuple) and r is tuple.__repr__) or
       
   171             (issubclass(typ, set) and r is set.__repr__) or
       
   172             (issubclass(typ, frozenset) and r is frozenset.__repr__)
       
   173            ):
       
   174             length = _len(object)
       
   175             if issubclass(typ, list):
       
   176                 write('[')
       
   177                 endchar = ']'
       
   178             elif issubclass(typ, set):
       
   179                 if not length:
       
   180                     write('set()')
       
   181                     return
       
   182                 write('set([')
       
   183                 endchar = '])'
       
   184                 object = sorted(object)
       
   185                 indent += 4
       
   186             elif issubclass(typ, frozenset):
       
   187                 if not length:
       
   188                     write('frozenset()')
       
   189                     return
       
   190                 write('frozenset([')
       
   191                 endchar = '])'
       
   192                 object = sorted(object)
       
   193                 indent += 10
       
   194             else:
       
   195                 write('(')
       
   196                 endchar = ')'
       
   197             if self._indent_per_level > 1 and sepLines:
       
   198                 write((self._indent_per_level - 1) * ' ')
       
   199             if length:
       
   200                 context[objid] = 1
       
   201                 indent = indent + self._indent_per_level
       
   202                 self._format(object[0], stream, indent, allowance + 1,
       
   203                              context, level)
       
   204                 if length > 1:
       
   205                     for ent in object[1:]:
       
   206                         if sepLines:
       
   207                             write(',\n' + ' '*indent)
       
   208                         else:
       
   209                             write(', ')
       
   210                         self._format(ent, stream, indent,
       
   211                                       allowance + 1, context, level)
       
   212                 indent = indent - self._indent_per_level
       
   213                 del context[objid]
       
   214             if issubclass(typ, tuple) and length == 1:
       
   215                 write(',')
       
   216             write(endchar)
       
   217             return
       
   218 
       
   219         write(rep)
       
   220 
       
   221     def _repr(self, object, context, level):
       
   222         repr, readable, recursive = self.format(object, context.copy(),
       
   223                                                 self._depth, level)
       
   224         if not readable:
       
   225             self._readable = False
       
   226         if recursive:
       
   227             self._recursive = True
       
   228         return repr
       
   229 
       
   230     def format(self, object, context, maxlevels, level):
       
   231         """Format object for a specific context, returning a string
       
   232         and flags indicating whether the representation is 'readable'
       
   233         and whether the object represents a recursive construct.
       
   234         """
       
   235         return _safe_repr(object, context, maxlevels, level)
       
   236 
       
   237 
       
   238 # Return triple (repr_string, isreadable, isrecursive).
       
   239 
       
   240 def _safe_repr(object, context, maxlevels, level):
       
   241     typ = _type(object)
       
   242     if typ is str:
       
   243         if 'locale' not in _sys.modules:
       
   244             return repr(object), True, False
       
   245         if "'" in object and '"' not in object:
       
   246             closure = '"'
       
   247             quotes = {'"': '\\"'}
       
   248         else:
       
   249             closure = "'"
       
   250             quotes = {"'": "\\'"}
       
   251         qget = quotes.get
       
   252         sio = _StringIO()
       
   253         write = sio.write
       
   254         for char in object:
       
   255             if char.isalpha():
       
   256                 write(char)
       
   257             else:
       
   258                 write(qget(char, repr(char)[1:-1]))
       
   259         return ("%s%s%s" % (closure, sio.getvalue(), closure)), True, False
       
   260 
       
   261     r = getattr(typ, "__repr__", None)
       
   262     if issubclass(typ, dict) and r is dict.__repr__:
       
   263         if not object:
       
   264             return "{}", True, False
       
   265         objid = _id(object)
       
   266         if maxlevels and level >= maxlevels:
       
   267             return "{...}", False, objid in context
       
   268         if objid in context:
       
   269             return _recursion(object), False, True
       
   270         context[objid] = 1
       
   271         readable = True
       
   272         recursive = False
       
   273         components = []
       
   274         append = components.append
       
   275         level += 1
       
   276         saferepr = _safe_repr
       
   277         for k, v in sorted(object.items()):
       
   278             krepr, kreadable, krecur = saferepr(k, context, maxlevels, level)
       
   279             vrepr, vreadable, vrecur = saferepr(v, context, maxlevels, level)
       
   280             append("%s: %s" % (krepr, vrepr))
       
   281             readable = readable and kreadable and vreadable
       
   282             if krecur or vrecur:
       
   283                 recursive = True
       
   284         del context[objid]
       
   285         return "{%s}" % _commajoin(components), readable, recursive
       
   286 
       
   287     if (issubclass(typ, list) and r is list.__repr__) or \
       
   288        (issubclass(typ, tuple) and r is tuple.__repr__):
       
   289         if issubclass(typ, list):
       
   290             if not object:
       
   291                 return "[]", True, False
       
   292             format = "[%s]"
       
   293         elif _len(object) == 1:
       
   294             format = "(%s,)"
       
   295         else:
       
   296             if not object:
       
   297                 return "()", True, False
       
   298             format = "(%s)"
       
   299         objid = _id(object)
       
   300         if maxlevels and level >= maxlevels:
       
   301             return format % "...", False, objid in context
       
   302         if objid in context:
       
   303             return _recursion(object), False, True
       
   304         context[objid] = 1
       
   305         readable = True
       
   306         recursive = False
       
   307         components = []
       
   308         append = components.append
       
   309         level += 1
       
   310         for o in object:
       
   311             orepr, oreadable, orecur = _safe_repr(o, context, maxlevels, level)
       
   312             append(orepr)
       
   313             if not oreadable:
       
   314                 readable = False
       
   315             if orecur:
       
   316                 recursive = True
       
   317         del context[objid]
       
   318         return format % _commajoin(components), readable, recursive
       
   319 
       
   320     rep = repr(object)
       
   321     return rep, (rep and not rep.startswith('<')), False
       
   322 
       
   323 
       
   324 def _recursion(object):
       
   325     return ("<Recursion on %s with id=%s>"
       
   326             % (_type(object).__name__, _id(object)))
       
   327 
       
   328 
       
   329 def _perfcheck(object=None):
       
   330     import time
       
   331     if object is None:
       
   332         object = [("string", (1, 2), [3, 4], {5: 6, 7: 8})] * 100000
       
   333     p = PrettyPrinter()
       
   334     t1 = time.time()
       
   335     _safe_repr(object, {}, None, 0)
       
   336     t2 = time.time()
       
   337     p.pformat(object)
       
   338     t3 = time.time()
       
   339     print "_safe_repr:", t2 - t1
       
   340     print "pformat:", t3 - t2
       
   341 
       
   342 if __name__ == "__main__":
       
   343     _perfcheck()