This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author rhettinger
Recipients afoglia, rhettinger
Date 2009-12-05.07:41:17
SpamBayes Score 4.915215e-10
Marked as misclassified No
Message-id <1259998880.57.0.741341349908.issue7434@psf.upfronthosting.co.za>
In-reply-to
Content
I agree with you that pprint needs to be rewritten to make it more
extensible.

I do not see a straight-forward way of handling your feature request.

First, namedtuple() is a factory function and is not itself a class, so
there is no standard way to recognize one.  Essentially, a named tuple
is concept (any class that supported both sequence behavior and
attribute access is a named tuple, for example the time structure is a
named tuple but not created by the collections.namedtuple() factory
function, instead is a C structseq which has substantially similar
characteristics).  This means that pprint has no reliable way to tell if
one of its arguments is a named tuple.

Second, collections.namedtuple() is intentionally designed to let the
user override the default __repr__() method (see an example in the
namedtuple docs).  That means that pprint cannot know in advance how a
named tuple is supposed to display.

At best, I can imagine that pprint() grows the ability to print a
multi-line repr (as specified by the object itself) but indented to a
level controlled by pprint().  The pprint() function would scan the repr
for newlines and replace them with a newline followed by the appropriate
number of spaces.

For example:

>>> class Point(namedtuple('Point', 'x y z')):
...     'Point with a multi-line repr'
...     def __repr__(self):
...         return 'Point(\n      x=%r,\n      y=%r,\n      z=%r\n    
)' % self

>>> Point(3,4,5)
Point(
      x=3,
      y=4,
      z=5
     )

>>> pprint([Point(3,4,5), Point(6,7,8)])
[Point(
       x=3,
       y=4,
       z=5
      ),
 Point(
       x=6,
       y=7,
       z=8
      )
]

Alternatively, the pprint module could introduce a new magic method to
support multi-line reprs when the repr itself it too long fit in a
single line:

class MyList(list):
...     def  __multirepr__(self):
...         'Return a list of strings to pprint'
...         return Multi(head = 'Mylist([',
...                      body = [str(x).upper() for x in self],
...                      tail = '])

>>> pprint(MyList(['now', 'is', 'the', 'time', 'for']), width=15)
MyList(['NOW',
        'IS',
        'THE',
        'TIME',
        'FOR',
])

In summary, there are several ways to approach this problem but they are
centered on building-out pprint(), not on changing collections.namedtuple().
History
Date User Action Args
2009-12-05 07:41:20rhettingersetrecipients: + rhettinger, afoglia
2009-12-05 07:41:20rhettingersetmessageid: <1259998880.57.0.741341349908.issue7434@psf.upfronthosting.co.za>
2009-12-05 07:41:19rhettingerlinkissue7434 messages
2009-12-05 07:41:17rhettingercreate