Author: Philip Jenvey <[email protected]>
Branch: py3k
Changeset: r71781:9b8b9359ea33
Date: 2014-05-29 12:22 -0700
http://bitbucket.org/pypy/pypy/changeset/9b8b9359ea33/
Log: fix space.hash to properly handle 'longs'
diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py
--- a/pypy/objspace/descroperation.py
+++ b/pypy/objspace/descroperation.py
@@ -433,15 +433,17 @@
raise oefmt(space.w_TypeError,
"'%T' objects are unhashable", w_obj)
w_result = space.get_and_call_function(w_hash, w_obj)
- w_resulttype = space.type(w_result)
- if space.is_w(w_resulttype, space.w_int):
+ if not space.isinstance_w(w_result, space.w_int):
+ raise oefmt(space.w_TypeError,
+ "__hash__ method should return an integer")
+
+ from pypy.objspace.std.intobject import W_IntObject
+ if type(w_result) is W_IntObject:
return w_result
- elif space.isinstance_w(w_result, space.w_int):
- # be careful about subclasses of 'int'...
+ elif isinstance(w_result, W_IntObject):
return space.wrap(space.int_w(w_result))
- else:
- raise OperationError(space.w_TypeError,
- space.wrap("__hash__() should return an int"))
+ # a non W_IntObject int, assume long-like
+ return w_result.descr_hash(space)
def userdel(space, w_obj):
w_del = space.lookup(w_obj, '__del__')
diff --git a/pypy/objspace/test/test_descroperation.py
b/pypy/objspace/test/test_descroperation.py
--- a/pypy/objspace/test/test_descroperation.py
+++ b/pypy/objspace/test/test_descroperation.py
@@ -715,6 +715,17 @@
return CannotConvertToBool()
x = X()
raises(MyError, "'foo' in x")
+
+ def test_64bit_hash(self):
+ import sys
+ class BigHash(object):
+ def __hash__(self):
+ return sys.maxsize + 2
+ def __eq__(self, other):
+ return isinstance(other, BigHash)
+ # previously triggered an OverflowError
+ d = {BigHash(): None}
+ assert BigHash() in d
class AppTestWithBuiltinShortcut(AppTest_Descroperation):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit