Issue #22721: An order of multiline pprint output of set or dict containing

orderable and non-orderable elements no longer depends on iteration order of
set or dict.
This commit is contained in:
Serhiy Storchaka 2015-04-06 22:52:44 +03:00
parent 01362da7d0
commit 62aa7dc7c9
3 changed files with 46 additions and 7 deletions

View File

@ -86,14 +86,10 @@ class _safe_key:
def __lt__(self, other):
try:
rv = self.obj.__lt__(other.obj)
return self.obj < other.obj
except TypeError:
rv = NotImplemented
if rv is NotImplemented:
rv = (str(type(self.obj)), id(self.obj)) < \
(str(type(other.obj)), id(other.obj))
return rv
return ((str(type(self.obj)), id(self.obj)) < \
(str(type(other.obj)), id(other.obj)))
def _safe_tuple(t):
"Helper function for comparing 2-tuples"

View File

@ -50,6 +50,25 @@ class Unorderable:
def __repr__(self):
return str(id(self))
# Class Orderable is orderable with any type
class Orderable:
def __init__(self, hash):
self._hash = hash
def __lt__(self, other):
return False
def __gt__(self, other):
return self != other
def __le__(self, other):
return self == other
def __ge__(self, other):
return True
def __eq__(self, other):
return self is other
def __ne__(self, other):
return self is not other
def __hash__(self):
return self._hash
class QueryTestCase(unittest.TestCase):
def setUp(self):
@ -620,6 +639,26 @@ frozenset2({0,
self.assertEqual(pprint.pformat(dict.fromkeys(keys, 0)),
'{%r: 0, %r: 0}' % tuple(sorted(keys, key=id)))
def test_sort_orderable_and_unorderable_values(self):
# Issue 22721: sorted pprints is not stable
a = Unorderable()
b = Orderable(hash(a)) # should have the same hash value
# self-test
self.assertLess(a, b)
self.assertLess(str(type(b)), str(type(a)))
self.assertEqual(sorted([b, a]), [a, b])
self.assertEqual(sorted([a, b]), [a, b])
# set
self.assertEqual(pprint.pformat(set([b, a]), width=1),
'{%r,\n %r}' % (a, b))
self.assertEqual(pprint.pformat(set([a, b]), width=1),
'{%r,\n %r}' % (a, b))
# dict
self.assertEqual(pprint.pformat(dict.fromkeys([b, a]), width=1),
'{%r: None,\n %r: None}' % (a, b))
self.assertEqual(pprint.pformat(dict.fromkeys([a, b]), width=1),
'{%r: None,\n %r: None}' % (a, b))
def test_str_wrap(self):
# pprint tries to wrap strings intelligently
fox = 'the quick brown fox jumped over a lazy dog'

View File

@ -19,6 +19,10 @@ Core and Builtins
Library
-------
- Issue #22721: An order of multiline pprint output of set or dict containing
orderable and non-orderable elements no longer depends on iteration order of
set or dict.
- Issue #15133: _tkinter.tkapp.getboolean() now supports Tcl_Obj and always
returns bool. tkinter.BooleanVar now validates input values (accepted bool,
int, str, and Tcl_Obj). tkinter.BooleanVar.get() now always returns bool.