mirror of https://github.com/python/cpython.git
144 lines
4.4 KiB
Python
144 lines
4.4 KiB
Python
|
# pprint.py
|
||
|
#
|
||
|
# Author: Fred L. Drake, Jr.
|
||
|
# fdrake@vt.edu
|
||
|
#
|
||
|
# 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 at least somewhat useful, especially in debugging
|
||
|
data structures.
|
||
|
|
||
|
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().
|
||
|
|
||
|
TAB_WIDTH -- The width represented by a single tab. This
|
||
|
value is typically 8, but 4 is the default
|
||
|
under MacOS. Can be changed by the user if
|
||
|
desired, but is probably not a good idea.
|
||
|
|
||
|
pprint(seq [, stream]) -- The pretty-printer. This takes a Python
|
||
|
object (presumably a sequence, but that
|
||
|
doesn't matter) and an optional output
|
||
|
stream. See the function documentation
|
||
|
for details.
|
||
|
"""
|
||
|
|
||
|
|
||
|
INDENT_PER_LEVEL = 1
|
||
|
|
||
|
MAX_WIDTH = 80
|
||
|
|
||
|
import os
|
||
|
TAB_WIDTH = (os.name == 'mac' and 4) or 8
|
||
|
del os
|
||
|
|
||
|
|
||
|
|
||
|
def _indentation(cols):
|
||
|
"Create tabbed indentation string COLS columns wide."
|
||
|
|
||
|
# This is used to reduce the byte-count for the output, allowing
|
||
|
# files created using this module to use as little external storage
|
||
|
# as possible. This is primarily intended to minimize impact on
|
||
|
# a user's quota when storing resource files, or for creating output
|
||
|
# intended for transmission.
|
||
|
|
||
|
return ((cols / TAB_WIDTH) * '\t') + ((cols % TAB_WIDTH) * ' ')
|
||
|
|
||
|
|
||
|
|
||
|
def pprint(seq, stream = None, indent = 0, allowance = 0):
|
||
|
"""Pretty-print a list, tuple, or dictionary.
|
||
|
|
||
|
pprint(seq [, stream]) ==> None
|
||
|
|
||
|
If STREAM is provided, output is written to that stream, otherwise
|
||
|
sys.stdout is used. 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 suite human-readable interpretation. The
|
||
|
output can be used as input without error, given readable
|
||
|
representations of all sequence elements are available via repr().
|
||
|
Output is restricted to MAX_WIDTH columns where possible. The
|
||
|
STREAM parameter must support the write() method with a single
|
||
|
parameter, which will always be a string. The output stream may be
|
||
|
a StringIO.StringIO object if the result is needed as a string.
|
||
|
"""
|
||
|
|
||
|
if stream is None:
|
||
|
import sys
|
||
|
stream = sys.stdout
|
||
|
|
||
|
from types import DictType, ListType, TupleType
|
||
|
|
||
|
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' + _indentation(indent))
|
||
|
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' + _indentation(indent) + rep)
|
||
|
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 pprint.py
|