Skip to content

bpo-28850: Fix PrettyPrinter.format overrides being ignored for contents of small containers#22120

Merged
taleinat merged 9 commits into
python:masterfrom
iritkatriel:PrettyPrinter
Nov 23, 2020
Merged

bpo-28850: Fix PrettyPrinter.format overrides being ignored for contents of small containers#22120
taleinat merged 9 commits into
python:masterfrom
iritkatriel:PrettyPrinter

Conversation

@iritkatriel

@iritkatriel iritkatriel commented Sep 6, 2020

Copy link
Copy Markdown
Member

This PR fixes a bug where subclassing PrettyPrinter and overriding format doesn't work for container contents (see issue 28850 for details).

The solution suggested here is to make _safe_repr a method of PrettyPrinter, and make it call self.format() when it needs to recurse on container contents.

The diff looks substantial, but that's mostly due to the indentation of _safe_repr code. To make it easier to review, I split it into several commits, where the indentation is done in one commit as a noop change. The other commits have much smaller diffs.

https://bugs.python.org/issue28850

@iritkatriel

Copy link
Copy Markdown
Member Author

FYI @serhiy-storchaka

Comment thread Lib/pprint.py Outdated
Comment thread Lib/pprint.py Outdated
Comment thread Misc/NEWS.d/next/Library/2020-09-06-21-55-44.bpo-28850.HJNggD.rst Outdated
Comment thread Lib/test/test_pprint.py Outdated
Comment thread Lib/pprint.py
Comment on lines 65 to +75
def saferepr(object):
"""Version of repr() which can handle recursive data structures."""
return _safe_repr(object, {}, None, 0, True)[0]
return PrettyPrinter()._safe_repr(object, {}, None, 0)[0]

def isreadable(object):
"""Determine if saferepr(object) is readable by eval()."""
return _safe_repr(object, {}, None, 0, True)[1]
return PrettyPrinter()._safe_repr(object, {}, None, 0)[1]

def isrecursive(object):
"""Determine if object requires a recursive representation."""
return _safe_repr(object, {}, None, 0, True)[2]
return PrettyPrinter()._safe_repr(object, {}, None, 0)[2]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems rather unfortunate that a PrettyPrinter() instance is now created here for every function call.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know. We could:

  1. leave _safe_repr where it was and pass in a function that it should call when it needs to recurse (default is it calls itself, but PrettyPrinter passes in self.format)

  2. move _safe_repr to a stateless superclass of PrettyPrinter, and instantiate a module level _defaultPrettyPrinter instance of this superclass for use in these functions.

Any other options?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO this is fine, and better than the alternatives.

@taleinat taleinat self-assigned this Nov 23, 2020

@taleinat taleinat left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@taleinat
taleinat merged commit ff420f0 into python:master Nov 23, 2020
@iritkatriel
iritkatriel deleted the PrettyPrinter branch November 23, 2020 14:12
@iritkatriel iritkatriel added the type-bug An unexpected behavior, bug, or error label Dec 23, 2020
adorilson pushed a commit to adorilson/cpython that referenced this pull request Mar 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type-bug An unexpected behavior, bug, or error

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants