This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author iritkatriel
Recipients anthonybaxter, doerwalter, georg.brandl, iritkatriel, markhirota, mic_e, rhettinger, xiang.zhang
Date 2020-09-06.16:31:30
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1599409890.63.0.140743882223.issue28850@roundup.psfhosted.org>
In-reply-to
Content
This issue only impacts container objects where  the len(repr(o)) is less than width. If the length is greater than width, containers are handled by a different code path which is covered by a unit test and works correctly.


For this case, indeed it works in Python 2 but not in Python 3. The PrettyPrinter._format code has been refactored quite a lot with respect to handling of containers.

In both Python 2 and 3 this happens:

PrettyPrinter.pprint([10]) calls
    PrettyPrinter._format([10])  which calls
	    PrettyPrinter._repr([10]) which calls
			MyPrettyPrinter.format([10]) which calls
			    PrettyPrinter.format([10]) which calls
				    _safe_repr([10])  which calls
					        _safe_repr(10)
							returns 10
					returns [10]
				returns [10]
			returns [10]
		returns [10]

But then they diverge - in Python 3 the [10] is returned as the result, but in Python 2 there is another piece of code (starting here https://github.com/python/cpython/blob/fdda200195f9747e411d3491aae0806bc1fcd919/Lib/pprint.py#L179) which overrides this result and recalculates the representation for containers. In our case it does:

		since issubclass(type([10]), list):
			# ignore the [10] calculated above, now call
			self._format(10) which calls
				PrettyPrinter._repr(10) which calls
					MyPrettyPrinter.format(10)
					returns 0xa
				returns 0xa
			returns 0xa
		returns [0xa]


This explains the difference between Python 2 and 3. 

As to why the first calculation returns [10] and not [0xa]:
This is because _safe_repr is defined at module scope, so once it is called we are no longer on the PrettyPrinter instance, and the format() override is no longer accessible.  When _safe_repr needs to recurse on container contents, it calls itself.


I think the solution is to make _safe_repr a method of PrettyPrinter, and make it call self.format() when it needs to recurse. The default self.format() just calls _safe_repr, so when there is no override the result is the same.

The PR's 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.
History
Date User Action Args
2020-09-06 16:31:30iritkatrielsetrecipients: + iritkatriel, doerwalter, anthonybaxter, georg.brandl, rhettinger, markhirota, mic_e, xiang.zhang
2020-09-06 16:31:30iritkatrielsetmessageid: <1599409890.63.0.140743882223.issue28850@roundup.psfhosted.org>
2020-09-06 16:31:30iritkatriellinkissue28850 messages
2020-09-06 16:31:30iritkatrielcreate