bpo-39994: Fix pprint handling of dict subclasses that override __repr__ (GH-21892)
Co-authored-by: Palak Kumar Jha
This commit is contained in:
parent
92c38164a4
commit
582f13786b
|
@ -176,12 +176,6 @@ class PrettyPrinter:
|
||||||
p(self, object, stream, indent, allowance, context, level + 1)
|
p(self, object, stream, indent, allowance, context, level + 1)
|
||||||
del context[objid]
|
del context[objid]
|
||||||
return
|
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)
|
stream.write(rep)
|
||||||
|
|
||||||
_dispatch = {}
|
_dispatch = {}
|
||||||
|
|
|
@ -18,6 +18,10 @@ class list3(list):
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return list.__repr__(self)
|
return list.__repr__(self)
|
||||||
|
|
||||||
|
class list_custom_repr(list):
|
||||||
|
def __repr__(self):
|
||||||
|
return '*'*len(list.__repr__(self))
|
||||||
|
|
||||||
class tuple2(tuple):
|
class tuple2(tuple):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -25,6 +29,10 @@ class tuple3(tuple):
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return tuple.__repr__(self)
|
return tuple.__repr__(self)
|
||||||
|
|
||||||
|
class tuple_custom_repr(tuple):
|
||||||
|
def __repr__(self):
|
||||||
|
return '*'*len(tuple.__repr__(self))
|
||||||
|
|
||||||
class set2(set):
|
class set2(set):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -32,6 +40,10 @@ class set3(set):
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return set.__repr__(self)
|
return set.__repr__(self)
|
||||||
|
|
||||||
|
class set_custom_repr(set):
|
||||||
|
def __repr__(self):
|
||||||
|
return '*'*len(set.__repr__(self))
|
||||||
|
|
||||||
class frozenset2(frozenset):
|
class frozenset2(frozenset):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -39,6 +51,10 @@ class frozenset3(frozenset):
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return frozenset.__repr__(self)
|
return frozenset.__repr__(self)
|
||||||
|
|
||||||
|
class frozenset_custom_repr(frozenset):
|
||||||
|
def __repr__(self):
|
||||||
|
return '*'*len(frozenset.__repr__(self))
|
||||||
|
|
||||||
class dict2(dict):
|
class dict2(dict):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -46,6 +62,10 @@ class dict3(dict):
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return dict.__repr__(self)
|
return dict.__repr__(self)
|
||||||
|
|
||||||
|
class dict_custom_repr(dict):
|
||||||
|
def __repr__(self):
|
||||||
|
return '*'*len(dict.__repr__(self))
|
||||||
|
|
||||||
class Unorderable:
|
class Unorderable:
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return str(id(self))
|
return str(id(self))
|
||||||
|
@ -155,7 +175,8 @@ class QueryTestCase(unittest.TestCase):
|
||||||
"expected not isreadable for %r" % (unreadable,))
|
"expected not isreadable for %r" % (unreadable,))
|
||||||
|
|
||||||
def test_same_as_repr(self):
|
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().
|
# For those the result should be the same as repr().
|
||||||
# Ahem. The docs don't say anything about that -- this appears to
|
# Ahem. The docs don't say anything about that -- this appears to
|
||||||
# be testing an implementation quirk. Starting in Python 2.5, it's
|
# be testing an implementation quirk. Starting in Python 2.5, it's
|
||||||
|
@ -187,6 +208,32 @@ class QueryTestCase(unittest.TestCase):
|
||||||
.replace('\n', ' '), native)
|
.replace('\n', ' '), native)
|
||||||
self.assertEqual(pprint.saferepr(simple), 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):
|
def test_basic_line_wrap(self):
|
||||||
# verify basic line-wrapping operation
|
# verify basic line-wrapping operation
|
||||||
o = {'RPM_cal': 0,
|
o = {'RPM_cal': 0,
|
||||||
|
|
|
@ -856,6 +856,7 @@ Per Øyvind Karlsen
|
||||||
Anton Kasyanov
|
Anton Kasyanov
|
||||||
Lou Kates
|
Lou Kates
|
||||||
Makoto Kato
|
Makoto Kato
|
||||||
|
Irit Katriel
|
||||||
Hiroaki Kawai
|
Hiroaki Kawai
|
||||||
Dmitry Kazakov
|
Dmitry Kazakov
|
||||||
Brian Kearns
|
Brian Kearns
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Fixed pprint's handling of dict subclasses that override __repr__.
|
Loading…
Reference in New Issue