I wish that singledispatch could be used for this, rather than adding yet another dunder method. Using a dunder method matches how things were historically done in Python. Also, since it’s for a builtin function to use, it’s logical to use a dunder for that too. However, I think it’s better if 3rd party packages are put on more equal footing with Python itself, i.e. they can define their own protocols and can use their own “namespace” for them without fear of conflicting.
I see that Rich uses __rich__ and __rich_console__ methods as protocol hooks. In practice that’s very likely fine since Python itself is unlikely to use those method names. However, those names really should be reserved for Python’s use.
If singledispatch is not up to the task, maybe we can fix it. That would make it more likely that other packages can use it, rather than just grabbing more dunder names for their own use.
I thought for a long time about using singledispatch. One problem was formatting namedtuples and dataclasses, neither of which have a common base class.
I thought about that, but it seems like it would be too easy to typo pprint when you wanted print, or vice versa, and too easy to easy to get visually confused, both in code and documentation, given that the two names are nearly identical.
Thanks for the vote of support @willmcgugan, for blazing the trail here, and especially for the early discussions leading to the adoption of Rich’s protocol.
For now, I am going to add this suggestion to the Open Issues, and we can bikeshed on the name as the PEP progresses. Another name that comes to mind is __pretty_repr__. I’m partial to the names without the interstitial underscores, and like that the original proposed name is evocative of the pprint module, but ultimately I’m open to persuasion.
Except that that is actually more complicated than just returning the bits to be printed. I’m thinking in particular about the case of print()'s file argument, which I think you’d have to support, and you get for free with the current proposal.
Keep in mind that __pprint__ doesn’t have to be a generator, but Will showed me examples where this seems like a natural coding style, so that’s what the examples use.
As for __getnewargs_ex__, I don’t think I want to conflate the pickle protocol with the pretty printing protocol. Two different purposes deserve two different methods.
I’d ask @willmcgugan whether he’s seen any complains from Rich users, since the protocol proposed in this PEP is exactly the same, and I think there’s benefit in riding on its shoulders.
“Equal to” explicitly means equality, i.e. ==, otherwise it would be an identity test, i.e. is.
Changing the existing pprint module is definitely out-of-scope of this PEP. I’m not sure whether pprint module improvements are PEP-worthy in and of themselves, or could be done through the normal PR process. If that’s something you want to work on, then I’d be interested to hear about specific ways the pretty printing protocol proposed here would have to change to support that idea, if at all.
Yes, but that subjectiveness is already baked into the existing pprint module. This proposal just ties a few existing things together without radically changing any of them.
But the pprint module doesn’t either, so we’re no worse off.
GUI debuggers could call __pprint__()[1] themselves and do Fancy Things with the values. One of the reasons I plumbed it through print() was to get file=stream for free.
This does seem compelling, and I wonder whether it further motivates naming the dunder __pformat__ (or similar) as suggested by Charles - since the formatting is the key mechanism, not the printing: