Pprint styling options?

Now that use of formatting tools is becoming pretty common, would it make any sense if the pretty print module could be extended to understand some of these (e.g. a style= kwarg)? To illustrate, if I snip the example from the pprint doc and put in a Python script I run black on, I’ll have something like:

pkginfo = {
    "author": "The Python Packaging Authority", 
    "author_email": "pypa-dev@googlegroups.com",
    "bugtrack_url": None,
    "classifiers": [
        "Development Status :: 3 - Alpha",
        "Intended Audience :: Developers",
        "License :: OSI Approved :: MIT License",
        "Programming Language :: Python :: 2",
        "Programming Language :: Python :: 2.6",
        "Programming Language :: Python :: 2.7",
        "Programming Language :: Python :: 3",
        "Programming Language :: Python :: 3.2",
        "Programming Language :: Python :: 3.3",
        "Programming Language :: Python :: 3.4",
        "Topic :: Software Development :: Build Tools",
    ],

and if I pprint that it comes out as:

{   'author': 'The Python Packaging Authority',
    'author_email': 'pypa-dev@googlegroups.com',
    'bugtrack_url': None,
    'classifiers': [   'Development Status :: 3 - Alpha',
                       'Intended Audience :: Developers',
                       'License :: OSI Approved :: MIT License',
                       'Programming Language :: Python :: 2',
                       'Programming Language :: Python :: 2.6',
                       'Programming Language :: Python :: 2.7',
                       'Programming Language :: Python :: 3',
                       'Programming Language :: Python :: 3.2',
                       'Programming Language :: Python :: 3.3',
                       'Programming Language :: Python :: 3.4',
                       'Topic :: Software Development :: Build Tools'],

Which is by no means wrong, but it’s a little irritating that it’s laid out differently than the original…

1 Like

This isn’t a complete answer, but for this specific cause you could use the json module to get a little closer to what you propose.

import json
print(json.dumps(pkginfo, indent=4))

prints:

{
    "author": "The Python Packaging Authority",
    "author_email": "pypa-dev@googlegroups.com",
    "bugtrack_url": null,
    "classifiers": [
        "Development Status :: 3 - Alpha",
        "Intended Audience :: Developers",
        "License :: OSI Approved :: MIT License",
        "Programming Language :: Python :: 2",
        "Programming Language :: Python :: 2.6",
        "Programming Language :: Python :: 2.7",
        "Programming Language :: Python :: 3",
        "Programming Language :: Python :: 3.2",
        "Programming Language :: Python :: 3.3",
        "Programming Language :: Python :: 3.4",
        "Topic :: Software Development :: Build Tools"
    ]
}
1 Like

-1 on this

What happens when one of these tools changes its format? Python is a lot slower to evolve than some libraries so we might not be able to catch up. In general, “Python’s APIs depending on other tools that use python” sounds a bit clunky to me.

But I am nether a core dev nor the author of any uncompromising formatters, <wink-wink>, so I can’t say for sure how good of an idea it is. It definitely deserves a discussion.

So let’s ask the most qualifiied person possible: @ambv, what do you think about it?

I hope this doesn’t come across as an obtuse question…
@mwichmann, does the indent argument mentioned in the pprint doc do the trick or does it just deepen the indents?
(Apologies for not testing this myself. I’m not near my laptop and only have my phone handy.)

class pprint.PrettyPrinter(indent=1, width=80, depth=None, stream=None, *, compact=False, sort_dicts=True, underscore_numbers=False)

@ambv, it seems that the behavior proposed here might be that the pprint parser have an option to make it a little less intelligent in aligning the split points. Something like simple=true or fancy=false could mute the smart indents and simply apply the indent= parameter without first aligning the split points. The style= mentioned in the OP is more open-ended whereas a binary argument is finite and therefore simpler to implement. The binary switch can also be rolled into a multivalued argument if other compelling indentation modes show up in the future and pass muster.

@storchaka might also have some valuable insights on this topic.

Indent does set (“fix”) the indentation level, but not necessarily where things are folded. If this hypothetical styling argument just takes an object that describes the rules, those don’t necessarily have to be built in to the pprint module (stdlib) itself, if there’s a worry about enshrining (and perhaps implicitly “blessing” some particular formatting layout). Clearly this is not a big deal, I was just surprised having gotten used to one style that my rare need to use pprint spit out something different…

That’s what I did.
Then I wanted to pretty print things that are not natively json serializable. Then I started implementing a custom json serializer so I could output e.g. datetime.
It was way too much effort for something that should be a styling option in pprint.

This sounds like it should be part of the tool whose style you want, like black.pprint, rather than in the standard library.

3 Likes

ISTM that the discussion (perhaps led on by the original post) is looking for an overly general solution. The only real feature request I see here for pprint is to get a new Boolean flag that makes it always put nested items on a new line (unless the whole thing fits on a new line), and also puts the closing brace/bracket/parenthesis on a new line by itself in that case. This happens to be what Black does, but there’s no need to invoke Black here – this has been a viable formatting option long before Black was written.

If someone wants to implement such a flag I’d be happy to review the design and code.

5 Likes