[pypy-commit] pypy default: unify the hash computation more with py3.5
arigo
pypy.commits at gmail.com
Wed May 9 12:57:53 EDT 2018
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r94505:52d2cf0086d1
Date: 2018-05-09 18:53 +0200
http://bitbucket.org/pypy/pypy/changeset/52d2cf0086d1/
Log: unify the hash computation more with py3.5
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
@@ -391,7 +391,6 @@
def descr_hash(self, space):
h = _hash_float(space, self.floatval)
- h -= (h == -1)
return space.newint(h)
def descr_format(self, space, w_spec):
@@ -716,8 +715,6 @@
# This must return the same hash as an equal int or long.
try:
x = ovfcheck_float_to_int(intpart)
- # Fits in a C long == a Python int, so is its own hash.
- return x
except OverflowError:
# Convert to long and use its hash.
try:
@@ -729,6 +726,10 @@
else:
return 314159
return space.int_w(space.hash(w_lval))
+ else:
+ # Fits in a C long == a Python int.
+ from pypy.objspace.std.intobject import _hash_int
+ return _hash_int(x)
# The fractional part is non-zero, so we don't have to worry about
# making this match the hash of some other type.
@@ -747,6 +748,7 @@
hipart = int(v) # take the top 32 bits
v = (v - hipart) * 2147483648.0 # get the next 32 bits
x = intmask(hipart + int(v) + (expo << 15))
+ x -= (x == -1)
return x
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
@@ -361,13 +361,7 @@
return _new_int(space, w_inttype, w_x, w_base)
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)
+ return space.newint(_hash_int(self.intval))
def _int(self, space):
return self.int(space)
@@ -893,3 +887,12 @@
__rpow__ = interp2app(W_IntObject.descr_rpow,
doc=W_AbstractIntObject.descr_rpow.__doc__),
)
+
+
+def _hash_int(a):
+ # 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.
+ #
+ return a - (a == -1) # No explicit condition, to avoid JIT bridges
diff --git a/pypy/objspace/std/specialisedtupleobject.py b/pypy/objspace/std/specialisedtupleobject.py
--- a/pypy/objspace/std/specialisedtupleobject.py
+++ b/pypy/objspace/std/specialisedtupleobject.py
@@ -1,7 +1,7 @@
from pypy.interpreter.error import oefmt
from pypy.objspace.std.tupleobject import W_AbstractTupleObject
from pypy.objspace.std.util import negate
-from rpython.rlib.objectmodel import compute_hash, specialize
+from rpython.rlib.objectmodel import specialize
from rpython.rlib.rarithmetic import intmask
from rpython.rlib.unroll import unrolling_iterable
from rpython.tool.sourcetools import func_with_new_name
@@ -71,18 +71,19 @@
value = getattr(self, 'value%s' % i)
if typetuple[i] == object:
y = space.int_w(space.hash(value))
- elif typetuple[i] == int:
- # mimic cpythons behavior of a hash value of -2 for -1
- y = value
- y -= (y == -1) # No explicit condition, to avoid JIT bridges
elif typetuple[i] == float:
# get the correct hash for float which is an
# integer & other less frequent cases
from pypy.objspace.std.floatobject import _hash_float
y = _hash_float(space, value)
- y -= (y == -1)
+ elif typetuple[i] == int:
+ # hash for int which is different from the hash
+ # given by rpython
+ from pypy.objspace.std.intobject import _hash_int
+ y = _hash_int(value)
else:
- assert 0, "unreachable"
+ raise NotImplementedError
+
x = (x ^ y) * mult
z -= 1
mult += 82520 + z + z
diff --git a/pypy/objspace/std/test/test_specialisedtupleobject.py b/pypy/objspace/std/test/test_specialisedtupleobject.py
--- a/pypy/objspace/std/test/test_specialisedtupleobject.py
+++ b/pypy/objspace/std/test/test_specialisedtupleobject.py
@@ -23,7 +23,7 @@
w_tuple = self.space.newtuple([self.space.wrap(1), self.space.wrap(2)])
assert w_tuple.__class__.__name__ == 'W_SpecialisedTupleObject_ii'
- def hash_test(self, values, must_be_specialized=True):
+ def hash_test(self, values, must_be_specialized):
N_values_w = [self.space.wrap(value) for value in values]
S_values_w = [self.space.wrap(value) for value in values]
N_w_tuple = W_TupleObject(N_values_w)
More information about the pypy-commit
mailing list