| #  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 |