[pypy-svn] r58722 - in pypy/branch/2.5-merge/pypy/objspace: . test
arigo at codespeak.net
arigo at codespeak.net
Tue Oct 7 13:27:06 CEST 2008
Author: arigo
Date: Tue Oct 7 13:27:05 2008
New Revision: 58722
Modified:
pypy/branch/2.5-merge/pypy/objspace/descroperation.py
pypy/branch/2.5-merge/pypy/objspace/test/test_descriptor.py
Log:
Test and fix: __hash__ could return subclasses of 'int' or 'long',
but that should be handled just like regular ints or longs.
Modified: pypy/branch/2.5-merge/pypy/objspace/descroperation.py
==============================================================================
--- pypy/branch/2.5-merge/pypy/objspace/descroperation.py (original)
+++ pypy/branch/2.5-merge/pypy/objspace/descroperation.py Tue Oct 7 13:27:05 2008
@@ -293,10 +293,18 @@
# XXX CPython has a special case for types with "__hash__ = None"
# to produce a nicer error message, namely "unhashable type: 'X'".
w_result = space.get_and_call_function(w_hash, w_obj)
- if space.is_true(space.isinstance(w_result, space.w_int)):
+ w_resulttype = space.type(w_result)
+ if space.is_w(w_resulttype, space.w_int):
return w_result
- elif space.is_true(space.isinstance(w_result, space.w_long)):
+ elif space.is_w(w_resulttype, space.w_long):
return space.hash(w_result)
+ elif space.is_true(space.isinstance(w_result, space.w_int)):
+ # be careful about subclasses of 'int'...
+ return space.wrap(space.int_w(w_result))
+ elif space.is_true(space.isinstance(w_result, space.w_long)):
+ # be careful about subclasses of 'long'...
+ bigint = space.bigint_w(w_result)
+ return space.wrap(bigint.hash())
else:
raise OperationError(space.w_TypeError,
space.wrap("__hash__() should return an int or long"))
Modified: pypy/branch/2.5-merge/pypy/objspace/test/test_descriptor.py
==============================================================================
--- pypy/branch/2.5-merge/pypy/objspace/test/test_descriptor.py (original)
+++ pypy/branch/2.5-merge/pypy/objspace/test/test_descriptor.py Tue Oct 7 13:27:05 2008
@@ -81,3 +81,22 @@
def __hash__(self):
return 1
assert isinstance(hash(G()), int)
+
+ # __hash__ can return a subclass of long, but the fact that it's
+ # a subclass is ignored
+ class mylong(long):
+ def __hash__(self):
+ return 0
+ class H(object):
+ def __hash__(self):
+ return mylong(42)
+ assert hash(H()) == hash(42L)
+
+ # don't return a subclass of int, either
+ class myint(int):
+ pass
+ class I(object):
+ def __hash__(self):
+ return myint(15)
+ assert hash(I()) == 15
+ assert type(hash(I())) is int
More information about the Pypy-commit
mailing list