[pypy-svn] r46474 - pypy/dist/pypy/module/_weakref

cfbolz at codespeak.net cfbolz at codespeak.net
Tue Sep 11 17:26:45 CEST 2007


Author: cfbolz
Date: Tue Sep 11 17:26:44 2007
New Revision: 46474

Modified:
   pypy/dist/pypy/module/_weakref/interp__weakref.py
Log:
rewrite the _weakref module to use the fancy new rweakref support.


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	Tue Sep 11 17:26:44 2007
@@ -4,96 +4,83 @@
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.typedef import GetSetProperty, TypeDef
 from pypy.interpreter.gateway import interp2app, ObjSpace
-from pypy.rlib.objectmodel import cast_weakgcaddress_to_object, cast_object_to_weakgcaddress
 from pypy.rpython.lltypesystem.llmemory import WEAKNULL
+import weakref
 
 
 class WeakrefLifeline(object):
     def __init__(self):
-        self.addr_refs = []
+        self.refs_weak = []
         self.cached_weakref_index = -1
         self.cached_proxy_index = -1
         
     def __del__(self):
-        for i in range(len(self.addr_refs) - 1, -1, -1):
-            addr_ref = self.addr_refs[i]
-            w_ref = cast_weakgcaddress_to_object(addr_ref, W_WeakrefBase)
-            if w_ref is not None:
-                w_ref.invalidate()
-        for i in range(len(self.addr_refs) - 1, -1, -1):
-            addr_ref = self.addr_refs[i]
-            w_ref = cast_weakgcaddress_to_object(addr_ref, W_WeakrefBase)
+        for i in range(len(self.refs_weak) - 1, -1, -1):
+            w_ref = self.refs_weak[i]()
             if w_ref is not None:
                 w_ref.activate_callback()
     
-    def get_weakref(self, space, w_subtype, w_obj, w_callable):
+    def get_or_make_weakref(self, space, w_subtype, w_obj, w_callable):
         w_weakreftype = space.gettypeobject(W_Weakref.typedef)
         is_weakreftype = space.is_w(w_weakreftype, w_subtype)
         can_reuse = space.is_w(w_callable, space.w_None)
         if is_weakreftype and can_reuse and self.cached_weakref_index >= 0:
-            cached_weakref_address = self.addr_refs[self.cached_weakref_index]
-            return cast_weakgcaddress_to_object(cached_weakref_address, W_Weakref)
+            w_cached = self.refs_weak[self.cached_weakref_index]()
+            if w_cached is not None:
+                return w_cached
+            else:
+                self.cached_weakref_index = -1
         w_ref = space.allocate_instance(W_Weakref, w_subtype)
-        index = len(self.addr_refs)
-        W_Weakref.__init__(w_ref, space, self, index,
-                           w_obj, w_callable)
-        self.addr_refs.append(cast_object_to_weakgcaddress(w_ref))
+        index = len(self.refs_weak)
+        W_Weakref.__init__(w_ref, space, w_obj, w_callable)
+        self.refs_weak.append(weakref.ref(w_ref))
         if is_weakreftype and can_reuse:
             self.cached_weakref_index = index
         return w_ref
 
-    def get_proxy(self, space, w_obj, w_callable):
+    def get_or_make_proxy(self, space, w_obj, w_callable):
         can_reuse = space.is_w(w_callable, space.w_None)
         if can_reuse and self.cached_proxy_index >= 0:
-            cached_proxy_address = self.addr_refs[self.cached_proxy_index]
-            return cast_weakgcaddress_to_object(cached_proxy_address, W_Proxy)
-        index = len(self.addr_refs)
+            w_cached = self.refs_weak[self.cached_proxy_index]()
+            if w_cached is not None:
+                return w_cached
+            else:
+                self.cached_proxy_index = -1
+        index = len(self.refs_weak)
         if space.is_true(space.callable(w_obj)):
-            w_proxy = W_CallableProxy(space, self, index, w_obj, w_callable)
+            w_proxy = W_CallableProxy(space, w_obj, w_callable)
         else:
-            w_proxy = W_Proxy(space, self, index, w_obj, w_callable)
-        self.addr_refs.append(cast_object_to_weakgcaddress(w_proxy))
+            w_proxy = W_Proxy(space, w_obj, w_callable)
+        self.refs_weak.append(weakref.ref(w_proxy))
         if can_reuse:
             self.cached_proxy_index = index
         return w_proxy
 
-    def ref_is_dead(self, index):
-        self.addr_refs[index] = WEAKNULL
-        if self.cached_proxy_index == index:
-            self.cached_proxy_index = -1
-        if self.cached_weakref_index == index:
-            self.cached_weakref_index = -1
-
     def get_any_weakref(self, space):
         if self.cached_weakref_index != -1:
-            return cast_weakgcaddress_to_object(
-                self.addr_refs[self.cached_weakref_index], W_Root)
+            w_ref = self.refs_weak[self.cached_weakref_index]()
+            if w_ref is not None:
+                return w_ref
         w_weakreftype = space.gettypeobject(W_Weakref.typedef)
-        for i in range(len(self.addr_refs)):
-            addr = self.addr_refs[i]
-            if cast_weakgcaddress_to_object(addr, W_Root) is not None:
-                w_ref = cast_weakgcaddress_to_object(addr, W_Root)
-                if space.is_true(space.isinstance(w_ref, w_weakreftype)):
-                    return w_ref
+        for i in range(len(self.refs_weak)):
+            w_ref = self.refs_weak[i]()
+            if (w_ref is not None and 
+                space.is_true(space.isinstance(w_ref, w_weakreftype))):
+                return w_ref
         return space.w_None
 
 class W_WeakrefBase(Wrappable):
-    def __init__(w_self, space, lifeline, index, w_obj, w_callable):
+    def __init__(w_self, space, w_obj, w_callable):
         w_self.space = space
-        w_self.address = cast_object_to_weakgcaddress(w_obj)
+        w_self.w_obj_weak = weakref.ref(w_obj)
         w_self.w_callable = w_callable
-        w_self.addr_lifeline = cast_object_to_weakgcaddress(lifeline)
-        w_self.index = index
 
     def dereference(self):
-        if cast_weakgcaddress_to_object(self.address, W_Root) is None:
+        w_obj = self.w_obj_weak()
+        if w_obj is None:
             return self.space.w_None
-        return cast_weakgcaddress_to_object(self.address, W_Root)
+        return w_obj
         
-    def invalidate(w_self):
-        w_self.address = WEAKNULL
-        w_self.addr_lifeline = WEAKNULL
-
     def activate_callback(w_self):
         if not w_self.space.is_w(w_self.w_callable, w_self.space.w_None):
             try:
@@ -101,15 +88,10 @@
             except OperationError, e:
                 e.write_unraisable(w_self.space, 'function', w_self.w_callable)
 
-    def __del__(w_self):
-        lifeline = cast_weakgcaddress_to_object(w_self.addr_lifeline,
-                                                WeakrefLifeline)
-        if lifeline is not None:
-            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)
+    def __init__(w_self, space, w_obj, w_callable):
+        W_WeakrefBase.__init__(w_self, space, w_obj, w_callable)
         w_self.w_hash = None
 
     def descr_hash(self):
@@ -127,13 +109,15 @@
     if lifeline is None:
         lifeline = WeakrefLifeline()
         w_obj.setweakref(space, lifeline)
-    return lifeline.get_weakref(space, w_subtype, w_obj, w_callable)
+    return lifeline.get_or_make_weakref(space, w_subtype, w_obj, w_callable)
 
 def descr__eq__(space, ref1, ref2):
-    if (cast_weakgcaddress_to_object(ref1.address, W_Root) is None or
-        cast_weakgcaddress_to_object(ref2.address, W_Root) is None):
+    w_obj1 = ref1.dereference()
+    w_obj2 = ref2.dereference()
+    if (space.is_w(w_obj1, space.w_None) or
+        space.is_w(w_obj2, space.w_None)):
         return space.is_(ref1, ref2)
-    return space.eq(ref1.dereference(), ref2.dereference())
+    return space.eq(w_obj1, w_obj2)
 
 def descr__ne__(space, ref1, ref2):
     return space.not_(space.eq(ref1, ref2))
@@ -159,8 +143,8 @@
         return space.wrap(0)
     else:
         result = 0
-        for i in range(len(lifeline.addr_refs)):
-            if cast_weakgcaddress_to_object(lifeline.addr_refs[i], W_Root) is not None:
+        for i in range(len(lifeline.refs_weak)):
+            if lifeline.refs_weak[i]() is not None:
                 result += 1
         return space.wrap(result)
 
@@ -171,10 +155,10 @@
         return space.newlist([])
     else:
         result = []
-        for i in range(len(lifeline.addr_refs)):
-            addr = lifeline.addr_refs[i]
-            if cast_weakgcaddress_to_object(addr, W_Root) is not None:
-                result.append(cast_weakgcaddress_to_object(addr, W_Root))
+        for i in range(len(lifeline.refs_weak)):
+            w_ref = lifeline.refs_weak[i]()
+            if w_ref is not None:
+                result.append(w_ref)
         return space.newlist(result)
 
 #_________________________________________________________________
@@ -198,7 +182,7 @@
     if lifeline is None:
         lifeline = WeakrefLifeline()
         w_obj.setweakref(space, lifeline) 
-    return lifeline.get_proxy(space, w_obj, w_callable)
+    return lifeline.get_or_make_proxy(space, w_obj, w_callable)
 
 def descr__new__proxy(space, w_subtype, w_obj, w_callable=None):
     raise OperationError(
@@ -255,21 +239,3 @@
                           unwrap_spec=['self', ObjSpace, Arguments]), 
     **callable_proxy_typedef_dict)
 W_CallableProxy.typedef.acceptable_as_base_class = False
-
-def basic_weakref(space, w_obj):
-    """this is a bit like the app-level weakref.ref(), but with no
-    fancy options like supporting subclasses of _weakref.ref and
-    callbacks."""
-    lifeline = w_obj.getweakref()
-    if lifeline is None:
-        lifeline = WeakrefLifeline()
-        w_obj.setweakref(space, lifeline)
-    if lifeline.cached_weakref_index >= 0:
-        cached_weakref_address = lifeline.addr_refs[lifeline.cached_weakref_index]
-        return cast_weakgcaddress_to_object(cached_weakref_address, W_Weakref)
-    index = len(lifeline.addr_refs)
-    w_ref = W_Weakref(space, lifeline, index, w_obj, space.w_None)
-    lifeline.addr_refs.append(cast_object_to_weakgcaddress(w_ref))
-    lifeline.cached_weakref_index = index
-    return w_ref
-    



More information about the Pypy-commit mailing list