cpython/Demo/parser/pprint.py

136 lines
3.8 KiB
Python
Raw Normal View History

1996-08-21 16:28:53 +00:00
# pprint.py
#
# Author: Fred L. Drake, Jr.
# fdrake@cnri.reston.va.us, fdrake@intr.net
1996-08-21 16:28:53 +00:00
#
# 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.
Constants
---------
1996-08-21 16:28:53 +00:00
INDENT_PER_LEVEL
Amount of indentation to use for each new recursive level. The
default is 1. This must be a non-negative integer, and may be set
by the caller before calling pprint().
MAX_WIDTH
Maximum width of the display. This is only used if the
representation *can* be kept less than MAX_WIDTH characters wide.
May be set by the user before calling pprint() if needed.
"""
1996-08-21 16:28:53 +00:00
INDENT_PER_LEVEL = 1
MAX_WIDTH = 80
from types import DictType, ListType, TupleType
1996-08-21 16:28:53 +00:00
def pformat(seq):
"""Format a Python object into a pretty-printed representation.
The representation is returned with no trailing newline.
1996-08-21 16:28:53 +00:00
"""
import StringIO
sio = StringIO.StringIO()
pprint(seq, stream=sio)
str = sio.getvalue()
if str and str[-1] == '\n':
str = str[:-1]
return str
1996-08-21 16:28:53 +00:00
def pprint(seq, stream=None, indent=0, allowance=0):
1996-08-21 16:28:53 +00:00
"""Pretty-print a list, tuple, or dictionary.
seq
List, tuple, or dictionary object to be pretty-printed. Other
object types are permitted by are not specially interpreted.
stream
Output stream. If not provided, `sys.stdout' is used. This
parameter must support the `write()' method with a single
parameter, which will always be a string. It may be a
`StringIO.StringIO' object if the result is needed as a
string.
Indentation is done according to `INDENT_PER_LEVEL', which may be
set to any non-negative integer before calling this function. The
output written on the stream is a perfectly valid representation
of the Python object passed in, with indentation to assist
human-readable interpretation. The output can be used as input
without error, given readable representations of all elements are
available via `repr()'. Output is restricted to `MAX_WIDTH'
columns where possible.
1996-08-21 16:28:53 +00:00
"""
if stream is None:
import sys
stream = sys.stdout
rep = `seq`
typ = type(seq)
sepLines = len(rep) > (MAX_WIDTH - 1 - indent - allowance)
if sepLines and (typ is ListType or typ is TupleType):
# Pretty-print the sequence.
stream.write(((typ is ListType) and '[') or '(')
length = len(seq)
if length:
indent = indent + INDENT_PER_LEVEL
pprint(seq[0], stream, indent, allowance + 1)
if len(seq) > 1:
for ent in seq[1:]:
stream.write(',\n' + ' '*indent)
1996-08-21 16:28:53 +00:00
pprint(ent, stream, indent, allowance + 1)
indent = indent - INDENT_PER_LEVEL
stream.write(((typ is ListType) and ']') or ')')
elif typ is DictType and sepLines:
stream.write('{')
length = len(seq)
if length:
indent = indent + INDENT_PER_LEVEL
items = seq.items()
items.sort()
key, ent = items[0]
rep = `key` + ': '
stream.write(rep)
pprint(ent, stream, indent + len(rep), allowance + 1)
if len(items) > 1:
for key, ent in items[1:]:
rep = `key` + ': '
stream.write(',\n' + ' '*indent + rep)
1996-08-21 16:28:53 +00:00
pprint(ent, stream, indent + len(rep), allowance + 1)
indent = indent - INDENT_PER_LEVEL
stream.write('}')
else:
stream.write(rep)
# Terminate the 'print' if we're not a recursive invocation.
if not indent:
stream.write('\n')
#
# end of file