diff -r 220b34cbd711 Doc/library/pprint.rst --- a/Doc/library/pprint.rst Sun Sep 29 18:59:27 2013 -0700 +++ b/Doc/library/pprint.rst Tue Oct 01 18:15:30 2013 +0300 @@ -29,14 +29,14 @@ .. First the implementation class: -.. class:: PrettyPrinter(indent=1, width=80, depth=None, stream=None) +.. class:: PrettyPrinter(indent=1, width=80, depth=None, stream=None, *, \ + compact=False) Construct a :class:`PrettyPrinter` instance. This constructor understands several keyword parameters. An output stream may be set using the *stream* keyword; the only method used on the stream object is the file protocol's :meth:`write` method. If not specified, the :class:`PrettyPrinter` adopts - ``sys.stdout``. Three additional parameters may be used to control the - formatted representation. The keywords are *indent*, *depth*, and *width*. The + ``sys.stdout``. The amount of indentation added for each recursive level is specified by *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 @@ -45,7 +45,9 @@ the depth of the objects being formatted. The desired output width is constrained using the *width* parameter; the default is 80 characters. If a structure cannot be formatted within the constrained width, a best effort will - be made. + be made. If *compact* is false (the default) each item of a long sequence + will be formatted on a separate line. If *compact* is true, as many items + as will fit within the *width* will be formatted on each output line. >>> import pprint >>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni'] @@ -58,6 +60,12 @@ 'lumberjack', 'knights', 'ni'] + >>> pp = pprint.PrettyPrinter(width=41, compact=True) + >>> pp.pprint(stuff) + [['spam', 'eggs', 'lumberjack', + 'knights', 'ni'], + 'spam', 'eggs', 'lumberjack', 'knights', + 'ni'] >>> tup = ('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead', ... ('parrot', ('fresh fruit',)))))))) >>> pp = pprint.PrettyPrinter(depth=6) @@ -67,21 +75,22 @@ The :mod:`pprint` module also provides several shortcut functions: -.. function:: pformat(object, indent=1, width=80, depth=None) +.. function:: pformat(object, indent=1, width=80, depth=None, *, compact=False) - Return the formatted representation of *object* as a string. *indent*, *width* - and *depth* will be passed to the :class:`PrettyPrinter` constructor as - formatting parameters. + Return the formatted representation of *object* as a string. *indent*, + *width*, *depth* and *compact* will be passed to the :class:`PrettyPrinter` + constructor as formatting parameters. -.. function:: pprint(object, stream=None, indent=1, width=80, depth=None) +.. function:: pprint(object, stream=None, indent=1, width=80, depth=None, *, \ + compact=False) Prints the formatted representation of *object* on *stream*, followed by a newline. If *stream* is ``None``, ``sys.stdout`` is used. This may be used in the interactive interpreter instead of the :func:`print` function for inspecting values (you can even reassign ``print = pprint.pprint`` for use - within a scope). *indent*, *width* and *depth* will be passed to the - :class:`PrettyPrinter` constructor as formatting parameters. + within a scope). *indent*, *width*, *depth* and *compact* will be passed + to the :class:`PrettyPrinter` constructor as formatting parameters. >>> import pprint >>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni'] diff -r 220b34cbd711 Lib/pprint.py --- a/Lib/pprint.py Sun Sep 29 18:59:27 2013 -0700 +++ b/Lib/pprint.py Tue Oct 01 18:15:30 2013 +0300 @@ -49,15 +49,18 @@ _type = type -def pprint(object, stream=None, indent=1, width=80, depth=None): +def pprint(object, stream=None, indent=1, width=80, depth=None, *, + compact=False): """Pretty-print a Python object to a stream [default is sys.stdout].""" printer = PrettyPrinter( - stream=stream, indent=indent, width=width, depth=depth) + stream=stream, indent=indent, width=width, depth=depth, + compact=compact) printer.pprint(object) -def pformat(object, indent=1, width=80, depth=None): +def pformat(object, indent=1, width=80, depth=None, *, compact=False): """Format a Python object into a pretty-printed representation.""" - return PrettyPrinter(indent=indent, width=width, depth=depth).pformat(object) + return PrettyPrinter(indent=indent, width=width, depth=depth, + compact=compact).pformat(object) def saferepr(object): """Version of repr() which can handle recursive data structures.""" @@ -102,7 +105,8 @@ return _safe_key(t[0]), _safe_key(t[1]) class PrettyPrinter: - def __init__(self, indent=1, width=80, depth=None, stream=None): + def __init__(self, indent=1, width=80, depth=None, stream=None, *, + compact=False): """Handle pretty printing operations onto a stream using a set of configured parameters. @@ -119,6 +123,9 @@ The desired output stream. If omitted (or false), the standard output stream available at construction will be used. + compact + If true, several items will be combined in one line. + """ indent = int(indent) width = int(width) @@ -132,6 +139,7 @@ self._stream = stream else: self._stream = _sys.stdout + self._compact = bool(compact) def pprint(self, object): self._format(object, self._stream, 0, 0, {}, 0) @@ -225,15 +233,9 @@ write((self._indent_per_level - 1) * ' ') if length: context[objid] = 1 - indent = indent + self._indent_per_level - self._format(object[0], stream, indent, allowance + 1, - context, level) - if length > 1: - for ent in object[1:]: - write(',\n' + ' '*indent) - self._format(ent, stream, indent, - allowance + 1, context, level) - indent = indent - self._indent_per_level + self._format_items(object, stream, + indent + self._indent_per_level, + allowance + 1, context, level) del context[objid] if issubclass(typ, tuple) and length == 1: write(',') @@ -273,6 +275,29 @@ return write(rep) + def _format_items(self, items, stream, indent, allowance, context, level): + write = stream.write + delimnl = ',\n' + ' ' * indent + delim = '' + width = max_width = self._width - indent - allowance + 2 + for ent in items: + if self._compact: + rep = self._repr(ent, context, level) + w = _len(rep) + 2 + if width < w: + width = max_width + if delim: + delim = delimnl + if width >= w: + width -= w + write(delim) + delim = ', ' + write(rep) + continue + write(delim) + delim = delimnl + self._format(ent, stream, indent, allowance, context, level) + def _repr(self, object, context, level): repr, readable, recursive = self.format(object, context.copy(), self._depth, level) diff -r 220b34cbd711 Lib/test/test_pprint.py --- a/Lib/test/test_pprint.py Sun Sep 29 18:59:27 2013 -0700 +++ b/Lib/test/test_pprint.py Tue Oct 01 18:15:30 2013 +0300 @@ -513,6 +513,18 @@ formatted = pprint.pformat(special, width=width) self.assertEqual(eval("(" + formatted + ")"), special) + def test_compact(self): + o = ([list(range(i * i)) for i in range(5)] + + [list(range(i)) for i in range(6)]) + expected = """\ +[[], [0], [0, 1, 2, 3], + [0, 1, 2, 3, 4, 5, 6, 7, 8], + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15], + [], [0], [0, 1], [0, 1, 2], [0, 1, 2, 3], + [0, 1, 2, 3, 4]]""" + self.assertEqual(pprint.pformat(o, width=48, compact=True), expected) + class DottedPrettyPrinter(pprint.PrettyPrinter):