diff options
author | Irit Katriel <iritkatriel@yahoo.com> | 2020-08-30 18:29:53 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-30 20:29:53 +0300 |
commit | 582f13786bb75c73d609790967fea03a5b50148a (patch) | |
tree | 18c1ca220cb3207c54fdb249b58a03a8391bb7db | |
parent | 92c38164a42572e2bc0b1b1490bec2369480ae08 (diff) | |
download | cpython-git-582f13786bb75c73d609790967fea03a5b50148a.tar.gz |
bpo-39994: Fix pprint handling of dict subclasses that override __repr__ (GH-21892)
Co-authored-by: Palak Kumar Jha
-rw-r--r-- | Lib/pprint.py | 6 | ||||
-rw-r--r-- | Lib/test/test_pprint.py | 49 | ||||
-rw-r--r-- | Misc/ACKS | 1 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2020-08-15-18-17-21.bpo-39994.dOgPOh.rst | 1 |
4 files changed, 50 insertions, 7 deletions
diff --git a/Lib/pprint.py b/Lib/pprint.py index 7c1118a484..213998e349 100644 --- a/Lib/pprint.py +++ b/Lib/pprint.py @@ -176,12 +176,6 @@ class PrettyPrinter: p(self, object, stream, indent, allowance, context, level + 1) del context[objid] return - elif isinstance(object, dict): - context[objid] = 1 - self._pprint_dict(object, stream, indent, allowance, - context, level + 1) - del context[objid] - return stream.write(rep) _dispatch = {} diff --git a/Lib/test/test_pprint.py b/Lib/test/test_pprint.py index cf3e4f093b..8ee18e8fef 100644 --- a/Lib/test/test_pprint.py +++ b/Lib/test/test_pprint.py @@ -18,6 +18,10 @@ class list3(list): def __repr__(self): return list.__repr__(self) +class list_custom_repr(list): + def __repr__(self): + return '*'*len(list.__repr__(self)) + class tuple2(tuple): pass @@ -25,6 +29,10 @@ class tuple3(tuple): def __repr__(self): return tuple.__repr__(self) +class tuple_custom_repr(tuple): + def __repr__(self): + return '*'*len(tuple.__repr__(self)) + class set2(set): pass @@ -32,6 +40,10 @@ class set3(set): def __repr__(self): return set.__repr__(self) +class set_custom_repr(set): + def __repr__(self): + return '*'*len(set.__repr__(self)) + class frozenset2(frozenset): pass @@ -39,6 +51,10 @@ class frozenset3(frozenset): def __repr__(self): return frozenset.__repr__(self) +class frozenset_custom_repr(frozenset): + def __repr__(self): + return '*'*len(frozenset.__repr__(self)) + class dict2(dict): pass @@ -46,6 +62,10 @@ class dict3(dict): def __repr__(self): return dict.__repr__(self) +class dict_custom_repr(dict): + def __repr__(self): + return '*'*len(dict.__repr__(self)) + class Unorderable: def __repr__(self): return str(id(self)) @@ -155,7 +175,8 @@ class QueryTestCase(unittest.TestCase): "expected not isreadable for %r" % (unreadable,)) def test_same_as_repr(self): - # Simple objects, small containers and classes that overwrite __repr__ + # Simple objects, small containers and classes that override __repr__ + # to directly call super's __repr__. # For those the result should be the same as repr(). # Ahem. The docs don't say anything about that -- this appears to # be testing an implementation quirk. Starting in Python 2.5, it's @@ -187,6 +208,32 @@ class QueryTestCase(unittest.TestCase): .replace('\n', ' '), native) self.assertEqual(pprint.saferepr(simple), native) + def test_container_repr_override_called(self): + N = 1000 + # Ensure that __repr__ override is called for subclasses of containers + + for cont in (list_custom_repr(), + list_custom_repr([1,2,3]), + list_custom_repr(range(N)), + tuple_custom_repr(), + tuple_custom_repr([1,2,3]), + tuple_custom_repr(range(N)), + set_custom_repr(), + set_custom_repr([1,2,3]), + set_custom_repr(range(N)), + frozenset_custom_repr(), + frozenset_custom_repr([1,2,3]), + frozenset_custom_repr(range(N)), + dict_custom_repr(), + dict_custom_repr({5: 6}), + dict_custom_repr(zip(range(N),range(N))), + ): + native = repr(cont) + expected = '*' * len(native) + self.assertEqual(pprint.pformat(cont), expected) + self.assertEqual(pprint.pformat(cont, width=1, indent=0), expected) + self.assertEqual(pprint.saferepr(cont), expected) + def test_basic_line_wrap(self): # verify basic line-wrapping operation o = {'RPM_cal': 0, @@ -856,6 +856,7 @@ Per Øyvind Karlsen Anton Kasyanov Lou Kates Makoto Kato +Irit Katriel Hiroaki Kawai Dmitry Kazakov Brian Kearns diff --git a/Misc/NEWS.d/next/Library/2020-08-15-18-17-21.bpo-39994.dOgPOh.rst b/Misc/NEWS.d/next/Library/2020-08-15-18-17-21.bpo-39994.dOgPOh.rst new file mode 100644 index 0000000000..46876c15ea --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-08-15-18-17-21.bpo-39994.dOgPOh.rst @@ -0,0 +1 @@ +Fixed pprint's handling of dict subclasses that override __repr__. |