[pypy-svn] r8578 - in pypy/dist/pypy/objspace: . std test
hpk at codespeak.net
hpk at codespeak.net
Tue Jan 25 17:43:08 CET 2005
Author: hpk
Date: Tue Jan 25 17:43:08 2005
New Revision: 8578
Modified:
pypy/dist/pypy/objspace/descroperation.py
pypy/dist/pypy/objspace/std/objecttype.py
pypy/dist/pypy/objspace/std/objspace.py
pypy/dist/pypy/objspace/test/test_descriptor.py
Log:
(Jacek and holger)
- after some discussion with Samuele we decided
that new style classes should be stricter
with respect to __hash__ operations:
in CPython only old-style classes would
raise TypeError("unhashable object") on code like:
class A:
def __eq__(self, other):
pass
hash(A())
and that was specifically tested in test_class.py
However, in PyPy which so far only has
new style classes we didn't do this
although it's probably a good idea.
Modified: pypy/dist/pypy/objspace/descroperation.py
==============================================================================
--- pypy/dist/pypy/objspace/descroperation.py (original)
+++ pypy/dist/pypy/objspace/descroperation.py Tue Jan 25 17:43:08 2005
@@ -228,6 +228,20 @@
if space.is_true(space.eq(w_next, w_item)):
return space.w_True
+ def hash(space, w_obj):
+ w_hash = space.lookup(w_obj, '__hash__')
+ if w_hash is None:
+ if space.lookup(w_obj, '__eq__') is not None or \
+ space.lookup(w_obj, '__cmp__') is not None:
+ raise OperationError(space.w_TypeError,
+ space.wrap("unhashable type"))
+ return space.id(w_obj)
+ w_result = space.get_and_call_function(w_hash, w_obj)
+ if space.is_true(space.isinstance(w_result, space.w_int)):
+ return w_result
+ else:
+ raise OperationError(space.w_TypeError,
+ space.wrap("__hash__() should return an int"))
# xxx round, ord
Modified: pypy/dist/pypy/objspace/std/objecttype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/objecttype.py (original)
+++ pypy/dist/pypy/objspace/std/objecttype.py Tue Jan 25 17:43:08 2005
@@ -14,11 +14,6 @@
def descr__str__(space, w_obj):
return space.repr(w_obj)
-def descr__hash__(space, w_obj):
- # XXX detect non-hashable instances (the ones overriding comparison only)
- # XXX ids could be long
- return space.id(w_obj)
-
def descr__class__(space, w_obj):
return space.type(w_obj)
@@ -49,7 +44,6 @@
__delattr__ = gateway.interp2app(Object.descr__delattr__.im_func),
__str__ = gateway.interp2app(descr__str__),
__repr__ = gateway.interp2app(descr__repr__),
- __hash__ = gateway.interp2app(descr__hash__),
__class__ = GetSetProperty(descr__class__),
__new__ = newmethod(descr__new__),
__init__ = gateway.interp2app(descr__init__),
Modified: pypy/dist/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/dist/pypy/objspace/std/objspace.py (original)
+++ pypy/dist/pypy/objspace/std/objspace.py Tue Jan 25 17:43:08 2005
@@ -364,21 +364,6 @@
else:
return DescrOperation.is_true(self, w_obj)
- def hash(space, w_obj):
- w = space.wrap
- eq = '__eq__'
- ne = '__ne__'
- hash_s = '__hash__'
-
- for w_t in space.type(w_obj).mro_w:
- d = w_t.dict_w
- if hash_s in d:
- w_descr = d[hash_s]
- return space.get_and_call_function(w_descr, w_obj)
- if eq in d:
- raise OperationError(space.w_TypeError, w("unhashable type"))
- return space.id(w_obj)
-
# add all regular multimethods to StdObjSpace
for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable:
if not hasattr(StdObjSpace.MM, _name):
Modified: pypy/dist/pypy/objspace/test/test_descriptor.py
==============================================================================
--- pypy/dist/pypy/objspace/test/test_descriptor.py (original)
+++ pypy/dist/pypy/objspace/test/test_descriptor.py Tue Jan 25 17:43:08 2005
@@ -50,3 +50,26 @@
raises(TypeError, oct, inst)
raises(TypeError, hex, inst)
assert A.seen == [1,2,3,4]
+
+class TestDesciprtorOnStd:
+ objspacename = 'std'
+ def test_hash(self):
+ class A:
+ pass
+ hash(A())
+ class B:
+ def __eq__(self, other): pass
+ raises(TypeError, hash, B())
+ class C:
+ def __cmp__(self, other): pass
+ raises(TypeError, "hash(C())")
+
+ class D:
+ def __hash__(self):
+ return 23L
+ raises(TypeError, hash, D())
+
+ class E:
+ def __hash__(self):
+ return "something"
+ raises(TypeError, hash, E())
More information about the Pypy-commit
mailing list