home *** CD-ROM | disk | FTP | other *** search
- # pprint.py
- #
- # Author: Fred L. Drake, Jr.
- # fdrake@cnri.reston.va.us, fdrake@intr.net
- #
- # 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
- ---------
-
- 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.
- """
-
- INDENT_PER_LEVEL = 1
-
- MAX_WIDTH = 80
-
- import os
- TAB_WIDTH = (os.name == 'mac' and 4) or 8
- del os
-
- from types import DictType, ListType, TupleType
-
-
- def _indentation(cols):
- """Create tabbed indentation string.
-
- cols
- Width of the indentation, in columns.
- """
- return ((cols / TAB_WIDTH) * '\t') + ((cols % TAB_WIDTH) * ' ')
-
-
- def pprint(seq, stream = None, indent = 0, allowance = 0):
- """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.
- """
- 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' + _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 file
-