[Python-checkins] CVS: python/dist/src/Lib pprint.py,1.16,1.17
Fred L. Drake
fdrake@users.sourceforge.net
Thu, 01 Nov 2001 09:50:40 -0800
Update of /cvsroot/python/python/dist/src/Lib
In directory usw-pr-cvs1:/tmp/cvs-serv22724
Modified Files:
pprint.py
Log Message:
Brute-force performance hackery; buys back about 20% of the time for
saferepr(), a bit less for pformat().
Index: pprint.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/pprint.py,v
retrieving revision 1.16
retrieving revision 1.17
diff -C2 -d -r1.16 -r1.17
*** pprint.py 2001/10/09 20:53:48 1.16
--- pprint.py 2001/11/01 17:50:38 1.17
***************
*** 46,49 ****
--- 46,57 ----
"PrettyPrinter"]
+ # cache these for faster access:
+ _commajoin = ", ".join
+ _sys_modules = sys.modules
+ _id = id
+ _len = len
+ _type = type
+
+
def pprint(object, stream=None):
"""Pretty-print a Python object to a stream [default is sys.sydout]."""
***************
*** 57,69 ****
def saferepr(object):
"""Version of repr() which can handle recursive data structures."""
! return _safe_repr(object, {})[0]
def isreadable(object):
"""Determine if saferepr(object) is readable by eval()."""
! return _safe_repr(object, {})[1]
def isrecursive(object):
"""Determine if object requires a recursive representation."""
! return _safe_repr(object, {})[2]
class PrettyPrinter:
--- 65,77 ----
def saferepr(object):
"""Version of repr() which can handle recursive data structures."""
! return _safe_repr(object, {}, None, 0)[0]
def isreadable(object):
"""Determine if saferepr(object) is readable by eval()."""
! return _safe_repr(object, {}, None, 0)[1]
def isrecursive(object):
"""Determine if object requires a recursive representation."""
! return _safe_repr(object, {}, None, 0)[2]
class PrettyPrinter:
***************
*** 109,113 ****
def isrecursive(self, object):
self.__recursive = 0
! self.pformat(object)
return self.__recursive
--- 117,121 ----
def isrecursive(self, object):
self.__recursive = 0
! self.__repr(object, {}, 0)
return self.__recursive
***************
*** 115,179 ****
self.__recursive = 0
self.__readable = 1
! self.pformat(object)
return self.__readable and not self.__recursive
def __format(self, object, stream, indent, allowance, context, level):
level = level + 1
! if context.has_key(id(object)):
! object = _Recursion(object)
self.__recursive = 1
rep = self.__repr(object, context, level - 1)
! objid = id(object)
! context[objid] = 1
! typ = type(object)
! sepLines = len(rep) > (self.__width - 1 - indent - allowance)
!
! if sepLines and typ in (ListType, TupleType):
! # Pretty-print the sequence.
! stream.write((typ is ListType) and '[' or '(')
! if self.__indent_per_level > 1:
! stream.write((self.__indent_per_level - 1) * ' ')
! length = len(object)
! if length:
! indent = indent + self.__indent_per_level
! self.__format(object[0], stream, indent, allowance + 1,
! context, level)
! if length > 1:
! for ent in object[1:]:
! stream.write(',\n' + ' '*indent)
! self.__format(ent, stream, indent,
! allowance + 1, context, level)
! indent = indent - self.__indent_per_level
! if typ is TupleType and length == 1:
! stream.write(',')
! stream.write(((typ is ListType) and ']') or ')')
! elif sepLines and typ is DictType:
! stream.write('{')
! if self.__indent_per_level > 1:
! stream.write((self.__indent_per_level - 1) * ' ')
! length = len(object)
! if length:
! indent = indent + self.__indent_per_level
! items = object.items()
! items.sort()
! key, ent = items[0]
! rep = self.__repr(key, context, level) + ': '
! stream.write(rep)
! self.__format(ent, stream, indent + len(rep),
! allowance + 1, context, level)
! if len(items) > 1:
! for key, ent in items[1:]:
! rep = self.__repr(key, context, level) + ': '
! stream.write(',\n' + ' '*indent + rep)
! self.__format(ent, stream, indent + len(rep),
! allowance + 1, context, level)
! indent = indent - self.__indent_per_level
! stream.write('}')
! else:
! stream.write(rep)
! del context[objid]
def __repr(self, object, context, level):
--- 123,198 ----
self.__recursive = 0
self.__readable = 1
! self.__repr(object, {}, 0)
return self.__readable and not self.__recursive
def __format(self, object, stream, indent, allowance, context, level):
level = level + 1
! objid = _id(object)
! if objid in context:
! stream.write(_recursion(object))
self.__recursive = 1
+ self.__readable = 0
+ return
rep = self.__repr(object, context, level - 1)
! typ = _type(object)
! sepLines = _len(rep) > (self.__width - 1 - indent - allowance)
! write = stream.write
! if sepLines:
! if typ is DictType:
! write('{')
! if self.__indent_per_level > 1:
! write((self.__indent_per_level - 1) * ' ')
! length = _len(object)
! if length:
! context[objid] = 1
! indent = indent + self.__indent_per_level
! items = object.items()
! items.sort()
! key, ent = items[0]
! rep = self.__repr(key, context, level)
! write(rep)
! write(': ')
! self.__format(ent, stream, indent + _len(rep) + 2,
! allowance + 1, context, level)
! if length > 1:
! for key, ent in items[1:]:
! rep = self.__repr(key, context, level)
! write(',\n%s: %s' % (' '*indent, rep))
! self.__format(ent, stream, indent + _len(rep) + 2,
! allowance + 1, context, level)
! indent = indent - self.__indent_per_level
! del context[objid]
! write('}')
! return
! if typ is ListType or typ is TupleType:
! if typ is ListType:
! write('[')
! endchar = ']'
! else:
! write('(')
! endchar = ')'
! if self.__indent_per_level > 1:
! write((self.__indent_per_level - 1) * ' ')
! length = _len(object)
! if length:
! context[objid] = 1
! indent = indent + self.__indent_per_level
! self.__format(object[0], stream, indent, allowance + 1,
! context, level)
! if length > 1:
! for ent in object[1:]:
! write(',\n' + ' '*indent)
! self.__format(ent, stream, indent,
! allowance + 1, context, level)
! indent = indent - self.__indent_per_level
! del context[objid]
! if typ is TupleType and length == 1:
! write(',')
! write(endchar)
! return
! write(rep)
def __repr(self, object, context, level):
***************
*** 188,201 ****
# Return triple (repr_string, isreadable, isrecursive).
! _have_module = sys.modules.has_key
!
! def _safe_repr(object, context, maxlevels=None, level=0):
! level += 1
! typ = type(object)
! if not (typ in (DictType, ListType, TupleType, StringType) and object):
! rep = `object`
! return rep, (rep and (rep[0] != '<')), 0
! elif typ is StringType:
! if not _have_module('locale'):
return `object`, 1, 0
if "'" in object and '"' not in object:
--- 207,214 ----
# Return triple (repr_string, isreadable, isrecursive).
! def _safe_repr(object, context, maxlevels, level):
! typ = _type(object)
! if typ is StringType:
! if 'locale' not in _sys_modules:
return `object`, 1, 0
if "'" in object and '"' not in object:
***************
*** 205,266 ****
closure = "'"
quotes = {"'": "\\'"}
sio = StringIO()
for char in object:
if char.isalpha():
! sio.write(char)
else:
! sio.write(quotes.get(char, `char`[1:-1]))
! return closure + sio.getvalue() + closure, 1, 0
!
! if context.has_key(id(object)):
! return `_Recursion(object)`, 0, 1
! objid = id(object)
! context[objid] = 1
!
! readable = 1
! recursive = 0
! startchar, endchar = {ListType: "[]",
! TupleType: "()",
! DictType: "{}"}[typ]
! if maxlevels and level > maxlevels:
! with_commas = "..."
! readable = 0
! elif typ is DictType:
components = []
for k, v in object.iteritems():
! krepr, kreadable, krecur = _safe_repr(k, context, maxlevels,
! level)
! vrepr, vreadable, vrecur = _safe_repr(v, context, maxlevels,
! level)
! components.append("%s: %s" % (krepr, vrepr))
readable = readable and kreadable and vreadable
! recursive = recursive or krecur or vrecur
! with_commas = ", ".join(components)
! else: # list or tuple
! assert typ in (ListType, TupleType)
components = []
! for element in object:
! subrepr, subreadable, subrecur = _safe_repr(
! element, context, maxlevels, level)
! components.append(subrepr)
! readable = readable and subreadable
! recursive = recursive or subrecur
! if len(components) == 1 and typ is TupleType:
! components[0] += ","
! with_commas = ", ".join(components)
- s = "%s%s%s" % (startchar, with_commas, endchar)
- del context[objid]
- return s, readable and not recursive, recursive
! class _Recursion:
! # represent a recursive relationship; really only used for the __repr__()
! # method...
! def __init__(self, object):
! self.__repr = "<Recursion on %s with id=%s>" \
! % (type(object).__name__, id(object))
! def __repr__(self):
! return self.__repr
--- 218,310 ----
closure = "'"
quotes = {"'": "\\'"}
+ qget = quotes.get
sio = StringIO()
+ write = sio.write
for char in object:
if char.isalpha():
! write(char)
else:
! write(qget(char, `char`[1:-1]))
! return ("%s%s%s" % (closure, sio.getvalue(), closure)), 1, 0
! if typ is DictType:
! if not object:
! return "{}", 1, 0
! objid = _id(object)
! if maxlevels and level > maxlevels:
! return "{...}", 0, objid in context
! if objid in context:
! return _recursion(object), 0, 1
! context[objid] = 1
! readable = 1
! recursive = 0
components = []
+ append = components.append
+ level += 1
+ saferepr = _safe_repr
for k, v in object.iteritems():
! krepr, kreadable, krecur = saferepr(k, context, maxlevels, level)
! vrepr, vreadable, vrecur = saferepr(v, context, maxlevels, level)
! append("%s: %s" % (krepr, vrepr))
readable = readable and kreadable and vreadable
! if krecur or vrecur:
! recursive = 1
! del context[objid]
! return "{%s}" % _commajoin(components), readable, recursive
! if typ is ListType or typ is TupleType:
! if typ is ListType:
! if not object:
! return "[]", 1, 0
! format = "[%s]"
! elif _len(object) == 1:
! format = "(%s,)"
! else:
! if not object:
! return "()", 1, 0
! format = "(%s)"
! objid = _id(object)
! if maxlevels and level > maxlevels:
! return format % "...", 0, objid in context
! if objid in context:
! return _recursion(object), 0, 1
! context[objid] = 1
! readable = 1
! recursive = 0
components = []
! append = components.append
! level += 1
! for o in object:
! orepr, oreadable, orecur = _safe_repr(o, context, maxlevels, level)
! append(orepr)
! if not oreadable:
! readable = 0
! if orecur:
! recursive = 1
! del context[objid]
! return format % _commajoin(components), readable, recursive
!
! rep = `object`
! return rep, (rep and not rep.startswith('<')), 0
! def _recursion(object):
! return ("<Recursion on %s with id=%s>"
! % (_type(object).__name__, _id(object)))
!
! def _perfcheck(object=None):
! import time
! if object is None:
! object = [("string", (1, 2), [3, 4], {5: 6, 7: 8})] * 100000
! p = PrettyPrinter()
! t1 = time.time()
! _safe_repr(object, {}, None, 0)
! t2 = time.time()
! p.pformat(object)
! t3 = time.time()
! print "_safe_repr:", t2 - t1
! print "pformat:", t3 - t2
!
! if __name__ == "__main__":
! _perfcheck()