[Python-checkins] cpython: Issue #22721: An order of multiline pprint output of set or dict containing

serhiy.storchaka python-checkins at python.org
Mon Apr 6 21:53:06 CEST 2015


https://hg.python.org/cpython/rev/c8815035116b
changeset:   95457:c8815035116b
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Mon Apr 06 22:52:44 2015 +0300
summary:
  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.

files:
  Lib/pprint.py           |  10 ++-----
  Lib/test/test_pprint.py |  39 +++++++++++++++++++++++++++++
  Misc/NEWS               |   4 ++
  3 files changed, 46 insertions(+), 7 deletions(-)


diff --git a/Lib/pprint.py b/Lib/pprint.py
--- a/Lib/pprint.py
+++ b/Lib/pprint.py
@@ -86,14 +86,10 @@
 
     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"
diff --git a/Lib/test/test_pprint.py b/Lib/test/test_pprint.py
--- a/Lib/test/test_pprint.py
+++ b/Lib/test/test_pprint.py
@@ -50,6 +50,25 @@
     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 @@
         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'
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -19,6 +19,10 @@
 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.

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list