[pypy-commit] pypy default: Restore a comment, and fix float.__hash__() and complex.__hash__() as well

arigo pypy.commits at gmail.com
Fri Aug 26 17:34:33 EDT 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r86585:6a2473172193
Date: 2016-08-26 23:33 +0200
http://bitbucket.org/pypy/pypy/changeset/6a2473172193/

Log:	Restore a comment, and fix float.__hash__() and complex.__hash__()
	as well

diff --git a/pypy/objspace/std/complexobject.py b/pypy/objspace/std/complexobject.py
--- a/pypy/objspace/std/complexobject.py
+++ b/pypy/objspace/std/complexobject.py
@@ -363,9 +363,10 @@
 
     def descr_hash(self, space):
         hashreal = _hash_float(space, self.realval)
-        hashimg = _hash_float(space, self.imagval)
-        combined = intmask(hashreal + 1000003 * hashimg)
-        return space.newint(combined)
+        hashimg = _hash_float(space, self.imagval)   # 0 if self.imagval == 0
+        h = intmask(hashreal + 1000003 * hashimg)
+        h -= (h == -1)
+        return space.newint(h)
 
     def descr_coerce(self, space, w_other):
         w_other = self._to_complex(space, w_other)
diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py
--- a/pypy/objspace/std/floatobject.py
+++ b/pypy/objspace/std/floatobject.py
@@ -390,7 +390,9 @@
         return space.wrap(float2string(self.floatval, 'g', DTSF_STR_PRECISION))
 
     def descr_hash(self, space):
-        return space.wrap(_hash_float(space, self.floatval))
+        h = _hash_float(space, self.floatval)
+        h -= (h == -1)
+        return space.wrap(h)
 
     def descr_format(self, space, w_spec):
         return newformat.run_formatter(space, w_spec, "format_float", self)
diff --git a/pypy/objspace/std/intobject.py b/pypy/objspace/std/intobject.py
--- a/pypy/objspace/std/intobject.py
+++ b/pypy/objspace/std/intobject.py
@@ -363,6 +363,9 @@
 
     def descr_hash(self, space):
         # For compatibility with CPython, we special-case -1
+        # Make sure this is consistent with the hash of floats and longs.
+        # The complete list of built-in types whose hash should be
+        # consistent is: int, long, bool, float, complex.
         h = self.intval
         h -= (h == -1)  # No explicit condition, to avoid JIT bridges
         return wrapint(space, h)
diff --git a/pypy/objspace/std/test/test_complexobject.py b/pypy/objspace/std/test/test_complexobject.py
--- a/pypy/objspace/std/test/test_complexobject.py
+++ b/pypy/objspace/std/test/test_complexobject.py
@@ -611,3 +611,7 @@
 
     def test_complex_two_arguments(self):
         raises(TypeError, complex, 5, None)
+
+    def test_hash_minus_one(self):
+        assert hash(-1.0 + 0j) == -2
+        assert (-1.0 + 0j).__hash__() == -2
diff --git a/pypy/objspace/std/test/test_floatobject.py b/pypy/objspace/std/test/test_floatobject.py
--- a/pypy/objspace/std/test/test_floatobject.py
+++ b/pypy/objspace/std/test/test_floatobject.py
@@ -455,6 +455,10 @@
         else:
             assert False, 'did not raise'
 
+    def test_hash_minus_one(self):
+        assert hash(-1.0) == -2
+        assert (-1.0).__hash__() == -2
+
 
 class AppTestFloatHex:
     spaceconfig = {


More information about the pypy-commit mailing list