[pypy-commit] pypy gc-del: Weakrefs, some small simplifications.
arigo
noreply at buildbot.pypy.org
Fri Apr 26 10:43:24 CEST 2013
Author: Armin Rigo <arigo at tunes.org>
Branch: gc-del
Changeset: r63629:8cf66f2f61cd
Date: 2013-04-26 10:29 +0200
http://bitbucket.org/pypy/pypy/changeset/8cf66f2f61cd/
Log: Weakrefs, some small simplifications.
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -165,7 +165,7 @@
self.invoke_finalizer()
def invoke_finalizer(self):
- raise NotImplementedError
+ raise NotImplementedError # must be overridden
def finalizer_perform(self, space, descrname, callback, *args):
"""For use in invoke_finalizer(). First check if we're called
diff --git a/pypy/module/_weakref/interp__weakref.py b/pypy/module/_weakref/interp__weakref.py
--- a/pypy/module/_weakref/interp__weakref.py
+++ b/pypy/module/_weakref/interp__weakref.py
@@ -3,7 +3,7 @@
from pypy.interpreter.error import OperationError
from pypy.interpreter.gateway import interp2app, ObjSpace
from pypy.interpreter.typedef import TypeDef
-from rpython.rlib import jit
+from rpython.rlib import rgc, jit
from rpython.rlib.rshrinklist import AbstractShrinkList
from rpython.rlib.objectmodel import specialize
import weakref
@@ -14,7 +14,7 @@
return wref() is not None
-class WeakrefLifeline(W_Root):
+class WeakrefLifeline(object):
cached_weakref = None
cached_proxy = None
other_refs_weak = None
@@ -97,37 +97,12 @@
return w_ref
return space.w_None
-
-class WeakrefLifelineWithCallbacks(WeakrefLifeline):
-
- def __init__(self, space, oldlifeline=None):
- self.space = space
- if oldlifeline is not None:
- self.cached_weakref = oldlifeline.cached_weakref
- self.cached_proxy = oldlifeline.cached_proxy
- self.other_refs_weak = oldlifeline.other_refs_weak
-
- def __del__(self):
- """This runs when the interp-level object goes away, and allows
- its lifeline to go away. The purpose of this is to activate the
- callbacks even if there is no __del__ method on the interp-level
- W_Root subclass implementing the object.
- """
- if self.other_refs_weak is None:
- return
- items = self.other_refs_weak.items()
- for i in range(len(items)-1, -1, -1):
- w_ref = items[i]()
- if w_ref is not None and w_ref.w_callable is not None:
- w_ref.enqueue_for_destruction(self.space,
- W_WeakrefBase.activate_callback,
- 'weakref callback of ')
-
def make_weakref_with_callback(self, w_subtype, w_obj, w_callable):
space = self.space
w_ref = space.allocate_instance(W_Weakref, w_subtype)
W_Weakref.__init__(w_ref, space, w_obj, w_callable)
self.append_wref_to(w_ref)
+ rgc.register_finalizer(self.finalizer)
return w_ref
def make_proxy_with_callback(self, w_obj, w_callable):
@@ -137,8 +112,24 @@
else:
w_proxy = W_Proxy(space, w_obj, w_callable)
self.append_wref_to(w_proxy)
+ rgc.register_finalizer(self.finalizer)
return w_proxy
+ def finalizer(self):
+ """This runs when the interp-level object goes away, and allows
+ its lifeline to go away. The purpose of this is to activate the
+ callbacks even if there is no __del__ method on the interp-level
+ W_Root subclass implementing the object.
+ """
+ assert self.other_refs_weak is not None
+ items = self.other_refs_weak.items()
+ for i in range(len(items)-1, -1, -1):
+ w_ref = items[i]()
+ if w_ref is not None and w_ref.w_callable is not None:
+ w_ref.finalizer_perform(self.space, 'weakref callback of ',
+ self.space.call_function,
+ w_ref.w_callable, w_ref)
+
# ____________________________________________________________
class Dummy:
@@ -166,10 +157,6 @@
def clear(self):
self.w_obj_weak = dead_ref
- def activate_callback(w_self):
- assert isinstance(w_self, W_WeakrefBase)
- w_self.space.call_function(w_self.w_callable, w_self)
-
def descr__repr__(self, space):
w_obj = self.dereference()
if w_obj is None:
@@ -232,21 +219,13 @@
w_obj.setweakref(space, lifeline)
return lifeline
-def getlifelinewithcallbacks(space, w_obj):
- lifeline = w_obj.getweakref()
- if not isinstance(lifeline, WeakrefLifelineWithCallbacks): # or None
- oldlifeline = lifeline
- lifeline = WeakrefLifelineWithCallbacks(space, oldlifeline)
- w_obj.setweakref(space, lifeline)
- return lifeline
-
@jit.dont_look_inside
def get_or_make_weakref(space, w_subtype, w_obj):
return getlifeline(space, w_obj).get_or_make_weakref(w_subtype, w_obj)
@jit.dont_look_inside
def make_weakref_with_callback(space, w_subtype, w_obj, w_callable):
- lifeline = getlifelinewithcallbacks(space, w_obj)
+ lifeline = getlifeline(space, w_obj)
return lifeline.make_weakref_with_callback(w_subtype, w_obj, w_callable)
def descr__new__weakref(space, w_subtype, w_obj, w_callable=None,
@@ -319,7 +298,7 @@
@jit.dont_look_inside
def make_proxy_with_callback(space, w_obj, w_callable):
- lifeline = getlifelinewithcallbacks(space, w_obj)
+ lifeline = getlifeline(space, w_obj)
return lifeline.make_proxy_with_callback(w_obj, w_callable)
def proxy(space, w_obj, w_callable=None):
diff --git a/pypy/module/_weakref/test/test_weakref.py b/pypy/module/_weakref/test/test_weakref.py
--- a/pypy/module/_weakref/test/test_weakref.py
+++ b/pypy/module/_weakref/test/test_weakref.py
@@ -1,6 +1,9 @@
class AppTestWeakref(object):
spaceconfig = dict(usemodules=('_weakref',))
-
+
+ def setup_class(cls):
+ cls.w_appdirect = cls.space.wrap(cls.runappdirect)
+
def test_simple(self):
import _weakref, gc
class A(object):
@@ -287,7 +290,11 @@
seen_del = []
class A(object):
def __del__(self):
- seen_del.append(id(self))
+ if self.appdirect:
+ my_id = id(self)
+ else:
+ my_id = aid # might be different when non-translated
+ seen_del.append(my_id)
seen_del.append(w1() is None)
seen_del.append(w2() is None)
seen_callback = []
More information about the pypy-commit
mailing list