%%  Author:  Fred L. Drake, Jr.		<fdrake@acm.org>

\section{Standard Module \module{pprint}}
\stmodindex{pprint}
\label{module-pprint}

The \module{pprint} module provides a capability to ``pretty-print''
arbitrary Python data structures in a form which can be used as input
to the interpreter.  If the formatted structures include objects which
are not fundamental Python types, the representation may not be
loadable.  This may be the case if objects such as files, sockets,
classes, or instances are included, as well as many other builtin
objects which are not representable as Python constants.

The formatted representation keeps objects on a single line if it can,
and breaks them onto multiple lines if they don't fit within the
allowed width.  Construct \class{PrettyPrinter} objects explicitly if
you need to adjust the width constraint.

The \module{pprint} module defines one class:


% First the implementation class:

\begin{classdesc}{PrettyPrinter}{...}
Construct a \class{PrettyPrinter} instance.  This constructor
understands several keyword parameters.  An output stream may be set
using the \var{stream} keyword; the only method used on the stream
object is the file protocol's \method{write()} method.  If not
specified, the \class{PrettyPrinter} adopts \code{sys.stdout}.  Three
additional parameters may be used to control the formatted
representation.  The keywords are \var{indent}, \var{depth}, and
\var{width}.  The amount of indentation added for each recursive level
is specified by \var{indent}; the default is one.  Other values can
cause output to look a little odd, but can make nesting easier to
spot.  The number of levels which may be printed is controlled by
\var{depth}; if the data structure being printed is too deep, the next
contained level is replaced by \samp{...}.  By default, there is no
constraint on the depth of the objects being formatted.  The desired
output width is constrained using the \var{width} parameter; the
default is eighty characters.  If a structure cannot be formatted
within the constrained width, a best effort will be made.

\begin{verbatim}
>>> import pprint, sys
>>> stuff = sys.path[:]
>>> stuff.insert(0, stuff[:])
>>> pp = pprint.PrettyPrinter(indent=4)
>>> pp.pprint(stuff)
[   [   '',
        '/usr/local/lib/python1.5',
        '/usr/local/lib/python1.5/test',
        '/usr/local/lib/python1.5/sunos5',
        '/usr/local/lib/python1.5/sharedmodules',
        '/usr/local/lib/python1.5/tkinter'],
    '',
    '/usr/local/lib/python1.5',
    '/usr/local/lib/python1.5/test',
    '/usr/local/lib/python1.5/sunos5',
    '/usr/local/lib/python1.5/sharedmodules',
    '/usr/local/lib/python1.5/tkinter']
>>>
>>> import parser
>>> tup = parser.ast2tuple(
...     parser.suite(open('pprint.py').read()))[1][1][1]
>>> pp = pprint.PrettyPrinter(depth=6)
>>> pp.pprint(tup)
(266, (267, (307, (287, (288, (...))))))
\end{verbatim}
\end{classdesc}


% Now the derivative functions:

The \class{PrettyPrinter} class supports several derivative functions:

\begin{funcdesc}{pformat}{object}
Return the formatted representation of \var{object} as a string.  The
default parameters for formatting are used.
\end{funcdesc}

\begin{funcdesc}{pprint}{object\optional{, stream}}
Prints the formatted representation of \var{object} on \var{stream},
followed by a newline.  If \var{stream} is omitted, \code{sys.stdout}
is used.  This may be used in the interactive interpreter instead of a
\keyword{print} statement for inspecting values.  The default
parameters for formatting are used.

\begin{verbatim}
>>> stuff = sys.path[:]
>>> stuff.insert(0, stuff)
>>> pprint.pprint(stuff)
[<Recursion on list with id=869440>,
 '',
 '/usr/local/lib/python1.5',
 '/usr/local/lib/python1.5/test',
 '/usr/local/lib/python1.5/sunos5',
 '/usr/local/lib/python1.5/sharedmodules',
 '/usr/local/lib/python1.5/tkinter']
\end{verbatim}
\end{funcdesc}

\begin{funcdesc}{isreadable}{object}
Determine if the formatted representation of \var{object} is
``readable,'' or can be used to reconstruct the value using
\function{eval()}\bifuncindex{eval}.  This always returns false for
recursive objects.

\begin{verbatim}
>>> pprint.isreadable(stuff)
0
\end{verbatim}
\end{funcdesc}

\begin{funcdesc}{isrecursive}{object}
Determine if \var{object} requires a recursive representation.
\end{funcdesc}


One more support function is also defined:

\begin{funcdesc}{saferepr}{object}
Return a string representation of \var{object}, protected against
recursive data structures.  If the representation of \var{object}
exposes a recursive entry, the recursive reference will be represented
as \samp{<Recursion on \var{typename} with id=\var{number}>}.  The
representation is not otherwise formatted.
\end{funcdesc}

% This example is outside the {funcdesc} to keep it from running over
% the right margin.
\begin{verbatim}
>>> pprint.saferepr(stuff)
"[<Recursion on list with id=682968>, '', '/usr/local/lib/python1.5', '/usr/loca
l/lib/python1.5/test', '/usr/local/lib/python1.5/sunos5', '/usr/local/lib/python
1.5/sharedmodules', '/usr/local/lib/python1.5/tkinter']"
\end{verbatim}


\subsection{PrettyPrinter Objects}
\label{PrettyPrinter Objects}

\class{PrettyPrinter} instances have the following methods:


\begin{methoddesc}{pformat}{object}
Return the formatted representation of \var{object}.  This takes into
Account the options passed to the \class{PrettyPrinter} constructor.
\end{methoddesc}

\begin{methoddesc}{pprint}{object}
Print the formatted representation of \var{object} on the configured
stream, followed by a newline.
\end{methoddesc}

The following methods provide the implementations for the
corresponding functions of the same names.  Using these methods on an
instance is slightly more efficient since new \class{PrettyPrinter}
objects don't need to be created.

\begin{methoddesc}{isreadable}{object}
Determine if the formatted representation of the object is
``readable,'' or can be used to reconstruct the value using
\function{eval()}\bifuncindex{eval}.  Note that this returns false for
recursive objects.  If the \var{depth} parameter of the
\class{PrettyPrinter} is set and the object is deeper than allowed,
this returns false.
\end{methoddesc}

\begin{methoddesc}{isrecursive}{object}
Determine if the object requires a recursive representation.
\end{methoddesc}
