Commit fed6bb7d authored by Georg Brandl's avatar Georg Brandl

Bug #1153: repr.repr() now doesn't require set and dictionary items

to be orderable to properly represent them.
 (backport from rev. 58122)
parent 226910f5
"""Redo the `...` (representation) but with limits on most sizes.""" """Redo the builtin repr() (representation) but with limits on most sizes."""
__all__ = ["Repr","repr"] __all__ = ["Repr","repr"]
...@@ -62,11 +62,11 @@ class Repr: ...@@ -62,11 +62,11 @@ class Repr:
return self._repr_iterable(x, level, header, '])', self.maxarray) return self._repr_iterable(x, level, header, '])', self.maxarray)
def repr_set(self, x, level): def repr_set(self, x, level):
x = sorted(x) x = _possibly_sorted(x)
return self._repr_iterable(x, level, 'set([', '])', self.maxset) return self._repr_iterable(x, level, 'set([', '])', self.maxset)
def repr_frozenset(self, x, level): def repr_frozenset(self, x, level):
x = sorted(x) x = _possibly_sorted(x)
return self._repr_iterable(x, level, 'frozenset([', '])', return self._repr_iterable(x, level, 'frozenset([', '])',
self.maxfrozenset) self.maxfrozenset)
...@@ -80,7 +80,7 @@ class Repr: ...@@ -80,7 +80,7 @@ class Repr:
newlevel = level - 1 newlevel = level - 1
repr1 = self.repr1 repr1 = self.repr1
pieces = [] pieces = []
for key in islice(sorted(x), self.maxdict): for key in islice(_possibly_sorted(x), self.maxdict):
keyrepr = repr1(key, newlevel) keyrepr = repr1(key, newlevel)
valrepr = repr1(x[key], newlevel) valrepr = repr1(x[key], newlevel)
pieces.append('%s: %s' % (keyrepr, valrepr)) pieces.append('%s: %s' % (keyrepr, valrepr))
...@@ -110,7 +110,7 @@ class Repr: ...@@ -110,7 +110,7 @@ class Repr:
s = __builtin__.repr(x) s = __builtin__.repr(x)
# Bugs in x.__repr__() can cause arbitrary # Bugs in x.__repr__() can cause arbitrary
# exceptions -- then make up something # exceptions -- then make up something
except: except Exception:
return '<%s instance at %x>' % (x.__class__.__name__, id(x)) return '<%s instance at %x>' % (x.__class__.__name__, id(x))
if len(s) > self.maxstring: if len(s) > self.maxstring:
i = max(0, (self.maxstring-3)//2) i = max(0, (self.maxstring-3)//2)
...@@ -118,5 +118,15 @@ class Repr: ...@@ -118,5 +118,15 @@ class Repr:
s = s[:i] + '...' + s[len(s)-j:] s = s[:i] + '...' + s[len(s)-j:]
return s return s
def _possibly_sorted(x):
# Since not all sequences of items can be sorted and comparison
# functions may raise arbitrary exceptions, return an unsorted
# sequence in that case.
try:
return sorted(x)
except Exception:
return list(x)
aRepr = Repr() aRepr = Repr()
repr = aRepr.repr repr = aRepr.repr
...@@ -197,6 +197,16 @@ class ReprTests(unittest.TestCase): ...@@ -197,6 +197,16 @@ class ReprTests(unittest.TestCase):
x = classmethod(C.foo) x = classmethod(C.foo)
self.failUnless(repr(x).startswith('<classmethod object at 0x')) self.failUnless(repr(x).startswith('<classmethod object at 0x'))
def test_unsortable(self):
# Repr.repr() used to call sorted() on sets, frozensets and dicts
# without taking into account that not all objects are comparable
x = set([1j, 2j, 3j])
y = frozenset(x)
z = {1j: 1, 2j: 2}
r(x)
r(y)
r(z)
def touch(path, text=''): def touch(path, text=''):
fp = open(path, 'w') fp = open(path, 'w')
fp.write(text) fp.write(text)
......
...@@ -32,6 +32,9 @@ Core and builtins ...@@ -32,6 +32,9 @@ Core and builtins
Library Library
------- -------
- Bug #1153: repr.repr() now doesn't require set and dictionary items
to be orderable to properly represent them.
- Bug #1709599: Run test_1565150 only if the file system is NTFS. - Bug #1709599: Run test_1565150 only if the file system is NTFS.
- When encountering a password-protected robots.txt file the RobotFileParser - When encountering a password-protected robots.txt file the RobotFileParser
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment