#  Author:	Fred L. Drake, Jr.
#		fdrake@cnri.reston.va.us, fdrake@acm.org
#
#  This is a simple little module I wrote to make life easier.  I didn't
#  see anything quite like it in the library, though I may have overlooked
#  something.  I wrote this when I was trying to read some heavily nested
#  tuples with fairly non-descriptive content.  This is modelled very much
#  after Lisp/Scheme - style pretty-printing of lists.  If you find it
#  useful, thank small children who sleep at night.

"""Support to pretty-print lists, tuples, & dictionaries recursively.

Very simple, but useful, especially in debugging data structures.

Classes
-------

PrettyPrinter()
    Handle pretty-printing operations onto a stream using a configured
    set of formatting parameters.

Functions
---------

pformat()
    Format a Python object into a pretty-printed representation.

pprint()
    Pretty-print a Python object to a stream [default is sys.sydout].

saferepr()
    Generate a 'standard' repr()-like value, but protect against recursive
    data structures.

"""

from types import DictType, ListType, TupleType

try:
    from cStringIO import StringIO
except ImportError:
    from StringIO import StringIO


def pprint(object, stream=None):
    """Pretty-print a Python object to a stream [default is sys.sydout]."""
    printer = PrettyPrinter(stream=stream)
    printer.pprint(object)


def pformat(object):
    """Format a Python object into a pretty-printed representation."""
    return PrettyPrinter().pformat(object)


def isreadable(object):
    """Determine if saferepr(object) is readable by eval()."""
    return PrettyPrinter().isreadable(object)


def isrecursive(object):
    """Determine if object requires a recursive representation."""
    return PrettyPrinter().isrecursive(object)


def saferepr(object):
    """Version of repr() which can handle recursive data structures."""
    return _safe_repr(object, {})[0]


class PrettyPrinter:
    def __init__(self, indent=1, width=80, depth=None, stream=None):
	"""Handle pretty printing operations onto a stream using a set of
	configured parameters.

	indent
	    Number of spaces to indent for each level of nesting.

	width
	    Attempted maximum number of columns in the output.

	depth
	    The maximum depth to print out nested structures.

	stream
	    The desired output stream.  If omitted (or false), the standard
	    output stream available at construction will be used.

	"""
	indent = int(indent)
	width = int(width)
	assert indent >= 0
	assert (not depth) or depth > 0, "depth may not be negative"
	assert width
	self.__depth = depth
	self.__indent_per_level = indent
	self.__width = width
	if stream:
	    self.__stream = stream
	else:
	    import sys
	    self.__stream = sys.stdout

    def pprint(self, object):
	self.__stream.write(self.pformat(object) + "\n")

    def pformat(self, object):
	sio = StringIO()
	self.__format(object, sio, 0, 0, {}, 0)
	return sio.getvalue()

    def isrecursive(self, object):
	self.__recursive = 0
	self.pformat(object)
	return self.__recursive

    def isreadable(self, object):
	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 len(object) > 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
	    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):
	repr, readable = _safe_repr(object, context, self.__depth, level)
	if not readable:
	    self.__readable = 0
	return repr


def _safe_repr(object, context, maxlevels=None, level=0):
    level = level + 1
    readable = 1
    typ = type(object)
    if not (typ in (DictType, ListType, TupleType) and object):
	rep = `object`
	if rep:
	    if rep[0] == '<':
		readable = 0
	else:
	    readable = 0
	return `object`, readable
    if context.has_key(id(object)):
	return `_Recursion(object)`, 0
    objid = id(object)
    context[objid] = 1
    if typ is DictType:
	if maxlevels and level >= maxlevels:
	    s = "{...}"
	    readable = 0
	else:
	    items = object.items()
	    k, v = items[0]
	    krepr, kreadable = _safe_repr(k, context, maxlevels, level)
	    vrepr, vreadable = _safe_repr(v, context, maxlevels, level)
	    readable = readable and kreadable and vreadable
	    s = "{%s: %s" % (krepr, vrepr)
	    for k, v in items[1:]:
		krepr, kreadable = _safe_repr(k, context, maxlevels, level)
		vrepr, vreadable = _safe_repr(v, context, maxlevels, level)
		readable = readable and kreadable and vreadable
		s = "%s, %s: %s" % (s, krepr, vrepr)
	    s = s + "}"
    else:
	s, term = (typ is ListType) and ('[', ']') or ('(', ')')
	if maxlevels and level >= maxlevels:
	    s = s + "..."
	    readable = 0
	else:
	    subrepr, subreadable = _safe_repr(
		object[0], context, maxlevels, level)
	    readable = readable and subreadable
	    s = s + subrepr
	    for ent in object[1:]:
		subrepr, subreadable = _safe_repr(
		    ent, context, maxlevels, level)
		readable = readable and subreadable
		s = "%s, %s" % (s, subrepr)
	s = s + term
    del context[objid]
    return s, readable


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
