When I try running this code:
from pprint import PrettyPrinter
class MyPrettyPrinter(PrettyPrinter):
def __init__(self, *args, **kwargs):
PrettyPrinter.__init__(self, *args, **kwargs)
def format(self, object, context, maxlevels, level):
(repr, readable, recursive) = PrettyPrinter.format(self, object, context, maxlevels, level)
return (type(repr)(object), readable, recursive) if isinstance(object, str) else (repr, readable, recursive)
print(MyPrettyPrinter().pformat(['x']))
I get a different output in Python 3 (['x']) than I get in Python 2 ([x]).
Why is this, and how do I get the same behavior as in Python 2?
This is how Python 3’s internal _format function works:
def _format(self, object, stream, indent, allowance, context, level):
# …
rep = self._repr(object, context, level - 1)
max_width = self._width - 1 - indent - allowance
sepLines = len(rep) > max_width
if sepLines:
# … custom repr logic
write(rep)
As you can see, if the the output of _repr fits into a single line, then no custom logic for generating the repr is used. self._repr delegates to self.format, which essentially just does a more complex repr(). So this is just called once if the output fits in a single line; otherwise, the output is not used but the (here: sequence) element is split into multiple parts, and the logic is again invoked for subelements.
In comparison, Python 2’s _format implements a completely custom logic at any stage, always invoking the custom formatter for all subelements in lists. That’s why your trigger works in Python 2 but does not in Python 3.
Unfortunately, I don’t see any simple way to hook into this without replicating a lot of the logic that’s in the new Python 3 implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With