[pypy-svn] r26467 - in pypy/dist/pypy/module/_weakref: . test
cfbolz at codespeak.net
cfbolz at codespeak.net
Thu Apr 27 23:12:14 CEST 2006
Author: cfbolz
Date: Thu Apr 27 23:12:11 2006
New Revision: 26467
Modified:
pypy/dist/pypy/module/_weakref/interp__weakref.py
pypy/dist/pypy/module/_weakref/test/test_weakref.py
Log:
make weakrefs properly hashable
Modified: pypy/dist/pypy/module/_weakref/interp__weakref.py
==============================================================================
--- pypy/dist/pypy/module/_weakref/interp__weakref.py (original)
+++ pypy/dist/pypy/module/_weakref/interp__weakref.py Thu Apr 27 23:12:11 2006
@@ -21,12 +21,12 @@
for i in range(len(self.addr_refs) - 1, -1, -1):
addr_ref = self.addr_refs[i]
if addr_ref != NULL:
- w_ref = cast_address_to_object(addr_ref, W_Weakref)
+ w_ref = cast_address_to_object(addr_ref, W_WeakrefBase)
w_ref.invalidate()
for i in range(len(self.addr_refs) - 1, -1, -1):
addr_ref = self.addr_refs[i]
if addr_ref != NULL:
- w_ref = cast_address_to_object(addr_ref, W_Weakref)
+ w_ref = cast_address_to_object(addr_ref, W_WeakrefBase)
w_ref.activate_callback()
def get_weakref(self, space, w_subtype, w_obj, w_callable):
@@ -62,7 +62,7 @@
self.addr_refs[index] = NULL
-class W_Weakref(Wrappable):
+class W_WeakrefBase(Wrappable):
def __init__(w_self, space, lifeline, index, w_obj, w_callable):
w_self.space = space
w_self.address = cast_object_to_address(w_obj)
@@ -91,6 +91,20 @@
WeakrefLifeline)
lifeline.ref_is_dead(w_self.index)
+class W_Weakref(W_WeakrefBase):
+ def __init__(w_self, space, lifeline, index, w_obj, w_callable):
+ W_WeakrefBase.__init__(w_self, space, lifeline, index, w_obj, w_callable)
+ w_self.w_hash = None
+
+ def descr_hash(self):
+ if self.w_hash is not None:
+ return self.w_hash
+ w_obj = self.dereference()
+ if self.space.is_w(w_obj, self.space.w_None):
+ raise OperationError(self.space.w_TypeError,
+ self.space.wrap("weak object has gone away"))
+ self.w_hash = self.space.hash(w_obj)
+ return self.w_hash
def descr__new__weakref(space, w_subtype, w_obj, w_callable=None):
assert isinstance(w_obj, W_Weakrefable)
@@ -112,6 +126,7 @@
unwrap_spec=[ObjSpace, W_Weakref, W_Weakref]),
__ne__ = interp2app(descr__ne__,
unwrap_spec=[ObjSpace, W_Weakref, W_Weakref]),
+ __hash__ = interp2app(W_Weakref.descr_hash, unwrap_spec=['self']),
__call__ = interp2app(W_Weakref.dereference, unwrap_spec=['self'])
)
@@ -140,13 +155,13 @@
for i in range(len(lifeline.addr_refs)):
addr = lifeline.addr_refs[i]
if addr != NULL:
- result.append(cast_address_to_object(addr, W_Weakref))
+ result.append(cast_address_to_object(addr, W_WeakrefBase))
return space.newlist(result)
#_________________________________________________________________
# Proxy
-class W_Proxy(W_Weakref):
+class W_Proxy(W_WeakrefBase):
def descr__hash__(self, space):
raise OperationError(space.w_TypeError,
space.wrap("unhashable type"))
Modified: pypy/dist/pypy/module/_weakref/test/test_weakref.py
==============================================================================
--- pypy/dist/pypy/module/_weakref/test/test_weakref.py (original)
+++ pypy/dist/pypy/module/_weakref/test/test_weakref.py Thu Apr 27 23:12:11 2006
@@ -118,6 +118,19 @@
ref1 = _weakref.ref(a)
assert _weakref.getweakrefs(a) == [ref1]
+ def test_hashing(self):
+ import _weakref
+ class A(object):
+ def __hash__(self):
+ return 42
+ a = A()
+ w = _weakref.ref(a)
+ assert hash(a) == hash(w)
+ del a
+ assert hash(w) == 42
+ w = _weakref.ref(A())
+ raises(TypeError, hash, w)
+
class AppTestProxy(object):
def setup_class(cls):
space = gettestobjspace(usemodules=('_weakref',))
More information about the Pypy-commit
mailing list