Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

general pprint rewrite #51683

Open
afoglia mannequin opened this issue Dec 4, 2009 · 18 comments
Open

general pprint rewrite #51683

afoglia mannequin opened this issue Dec 4, 2009 · 18 comments
Labels
stdlib Python modules in the Lib dir type-feature A feature request or enhancement

Comments

@afoglia
Copy link
Mannequin

afoglia mannequin commented Dec 4, 2009

BPO 7434
Nosy @warsaw, @birkenfeld, @rhettinger, @ncoghlan, @abalkin, @pitrou, @jackdied, @giampaolo, @mitsuhiko, @ezio-melotti, @merwok, @4kir4, @ambv, @ericsnowcurrently, @serhiy-storchaka, @RazerM
Files
  • rdh_pprint.py: Technique for attaching handlers.
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = None
    created_at = <Date 2009-12-04.16:32:41.835>
    labels = ['type-feature', 'library']
    title = 'general pprint rewrite'
    updated_at = <Date 2016-12-15.07:42:40.945>
    user = 'https://bugs.python.org/afoglia'

    bugs.python.org fields:

    activity = <Date 2016-12-15.07:42:40.945>
    actor = 'astenberg'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = ['Library (Lib)']
    creation = <Date 2009-12-04.16:32:41.835>
    creator = 'afoglia'
    dependencies = []
    files = ['19888']
    hgrepos = []
    issue_num = 7434
    keywords = []
    message_count = 18.0
    messages = ['95968', '95983', '96011', '96014', '99530', '99534', '99554', '118516', '122037', '122968', '138818', '189750', '207287', '207299', '207300', '207301', '218873', '283212']
    nosy_count = 25.0
    nosy_names = ['barry', 'georg.brandl', 'rhettinger', 'ncoghlan', 'belopolsky', 'pitrou', 'jackdied', 'giampaolo.rodola', 'aronacher', 'ezio.melotti', 'eric.araujo', 'afoglia', 'abacabadabacaba', 'santoso.wijaya', 'akira', 'lukasz.langa', 'ssc', 'eric.snow', 'gwrtheyrn', 'serhiy.storchaka', 'dugres', 'eddygeek', 'Ezekiel.Fairfax', 'RazerM', 'astenberg']
    pr_nums = []
    priority = 'low'
    resolution = 'later'
    stage = None
    status = 'open'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue7434'
    versions = ['Python 3.5']

    @afoglia
    Copy link
    Mannequin Author

    afoglia mannequin commented Dec 4, 2009

    It would be nice if pprint could format namedtuples wrapping lines as it
    does with tuples.

    Looking at the code, this does not look like an easy task. Completely
    rewriting pprint to allow it to be extensible to user-created classes
    would be best, but involve a ton of work. Simple making all named
    tuples derive from a named tuple base class (itself derived from tuple)
    would be simpler, albeit more of a hack.

    @afoglia afoglia mannequin added stdlib Python modules in the Lib dir type-feature A feature request or enhancement labels Dec 4, 2009
    @rhettinger
    Copy link
    Contributor

    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().

    @rhettinger rhettinger removed their assignment Dec 5, 2009
    @pitrou
    Copy link
    Member

    pitrou commented Dec 5, 2009

    You could make all namedtuples inherit from a common base class, e.g.
    BaseNamedTuple.

    @rhettinger
    Copy link
    Contributor

    We need a more generic solution that allows multi-line reprs for a
    variety of types. Here is an example that doesn't involve named tuples:

    >>> pprint(s, width=15)
    [OrderedDict([('x', 30000000000), ('y', 4000000000), ('z', 5000000000)]),
     OrderedDict([('x', 6000000000), ('y', 70000000), ('z', 8000000000)])]

    What we want is to have it print like regular dictionaries do:

    >>> pprint([dict(p) for p in s], width=15)
    [{'x': 30000000000,
      'y': 4000000000,
      'z': 5000000000},
     {'x': 6000000000,
      'y': 70000000,
      'z': 8000000000}]

    It would also be nice if pprint could accept arguments telling it how to
    format various types:

    >>> pprint(s, width=15, format={int: '15,'})
    [{'x': ' 30,000,000,000',
      'y': '  4,000,000,000',
      'z': '  5,000,000,000'},
     {'x': '  6,000,000,000',
      'y': '     70,000,000',
      'z': '  8,000,000,000'}]

    @benjaminp benjaminp assigned rhettinger and unassigned rhettinger Feb 18, 2010
    @benjaminp
    Copy link
    Contributor

    Sorry for the noise...

    @rhettinger
    Copy link
    Contributor

    Will ponder this a bit more but will likely close this specific request (leaving open the possibility of a more general rewrite of pprint).

    @rhettinger rhettinger self-assigned this Feb 18, 2010
    @pitrou
    Copy link
    Member

    pitrou commented Feb 19, 2010

    Could something like a generic __pprint__ hook achieve this?

    @ambv
    Copy link
    Contributor

    ambv commented Oct 13, 2010

    I would like to work on that. Expect a patch soon.

    Georg, Fred, I've added you to nosy because you're the ones watching over me currently. Bare with me :)

    @ambv ambv changed the title pprint doesn't know how to print a namedtuple general pprint rewrite Oct 13, 2010
    @rhettinger
    Copy link
    Contributor

    Deferring the general rewrite until 3.3.
    It would need to have a lot of people look
    at it and evaluate it. I no longer think
    there is time for that before the 3.2 beta.

    @rhettinger
    Copy link
    Contributor

    Attaching a rough concept of how to make the existing pprint module extendible without doing a total rewrite. The actual handler is currently bogus (no thought out), so focus on the @guard decorator and the technique for scanning for handlers.

    @rhettinger
    Copy link
    Contributor

    Link to Armin's work on a pprint improvement based on a Ruby pprint tool: https://github.com/mitsuhiko/prettyprint

    @ambv
    Copy link
    Contributor

    ambv commented May 21, 2013

    For the record, my class-based approach from 2010 still available here:

    https://bitbucket.org/ambv/nattyprint

    @rhettinger rhettinger removed their assignment Jul 12, 2013
    @ncoghlan
    Copy link
    Contributor

    ncoghlan commented Jan 4, 2014

    With PEP-443 added for Python 3.4, I believe Łukasz intended to pursue a new pprint implementation based on functools.singledispatch.

    That has obviously missed feature freeze for Python 3.4, but it's still a reasonable idea to pursue for 3.5.

    In addition to OrderedDict (mentioned above) and defaultdict (which was mentioned in bpo-5131), an updated pprint would also allow us to add support for the new dict view types, collections.deque, etc.

    Ideally, we'd also have a standard lazy import mechanism in 3.5, so these definitions could go in the collections module, but only installed if pprint was also imported. Otherwise, having pprint depend on collections would likely be preferable to having the dependency run the other way.

    @pitrou
    Copy link
    Member

    pitrou commented Jan 4, 2014

    Ideally, we'd also have a standard lazy import mechanism in 3.5, so these definitions could go in the collections module, but only installed if pprint was also imported.

    That sounds more like an on-import hook than a lazy import mechanism, no?

    @pitrou pitrou added the easy label Jan 4, 2014
    @pitrou
    Copy link
    Member

    pitrou commented Jan 4, 2014

    Oops... no, it's not easy.

    @pitrou
    Copy link
    Member

    pitrou commented Jan 4, 2014

    Ok, so why did Roundup add the easy keyword and doesn't want to remove it?

    @ezio-melotti ezio-melotti removed the easy label Jan 4, 2014
    @4kir4
    Copy link
    Mannequin

    4kir4 mannequin commented May 21, 2014

    Related issue bpo-21542: pprint support for multiline collections.Counter

    @dugres
    Copy link
    Mannequin

    dugres mannequin commented Dec 14, 2016

    I've made a Pretty Printer and I'd like to know if anybody thinks it could of some help here. (I do)

    It's easily extensible and customizable to support any type in any way.

    https://github.com/louis-riviere-xyz/prettypy.git

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    stdlib Python modules in the Lib dir type-feature A feature request or enhancement
    Projects
    None yet
    Development

    No branches or pull requests

    6 participants