[pypy-commit] pypy gc-del: Progress: __del__ works again on new-style classes.

arigo noreply at buildbot.pypy.org
Thu Apr 25 18:16:17 CEST 2013


Author: Armin Rigo <arigo at tunes.org>
Branch: gc-del
Changeset: r63611:57387227c7ab
Date: 2013-04-25 17:41 +0200
http://bitbucket.org/pypy/pypy/changeset/57387227c7ab/

Log:	Progress: __del__ works again on new-style classes.

diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -237,6 +237,17 @@
                 self.space = space
                 self.w__class__ = w_subtype
                 self.user_setup_slots(w_subtype.nslots)
+                if w_subtype.has_del:
+                    self.register_finalizer()
+
+            def invoke_finalizer(self):
+                space = self.space
+                w_descr = space.lookup(self, '__del__')
+                if w_descr is None:
+                    return
+                self.finalizer_perform(self.space, "__del__ method of ",
+                                       space.get_and_call_function,
+                                       w_descr, self)
 
             def user_setup_slots(self, nslots):
                 assert nslots == 0
diff --git a/pypy/module/__builtin__/interp_classobj.py b/pypy/module/__builtin__/interp_classobj.py
--- a/pypy/module/__builtin__/interp_classobj.py
+++ b/pypy/module/__builtin__/interp_classobj.py
@@ -694,7 +694,7 @@
         if w_func is None:
             w_func = self.getattr_from_class(space, '__del__')
         if w_func is not None:
-            self.finalizer_perform(self.space, "__del__ of ",
+            self.finalizer_perform(self.space, "__del__ method of ",
                                    space.call_function, w_func)
 
     def descr_exit(self, space, w_type, w_value, w_tb):
diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py
--- a/pypy/module/_socket/interp_socket.py
+++ b/pypy/module/_socket/interp_socket.py
@@ -132,9 +132,12 @@
 
 
 class W_RSocket(Wrappable, RSocket):
+    def __init__(self, family, type, proto):
+        RSocket.__init__(self, family, type, proto)
+        self.register_finalizer()
+
     def invoke_finalizer(self):
-        self.clear_all_weakrefs()
-        RSocket.invoke_finalizer(self)
+        RSocket.invoke_finalizer(self)     # destroy the socket fd
 
     def accept_w(self, space):
         """accept() -> (socket object, address info)
diff --git a/pypy/objspace/std/model.py b/pypy/objspace/std/model.py
--- a/pypy/objspace/std/model.py
+++ b/pypy/objspace/std/model.py
@@ -344,7 +344,7 @@
     "Parent base class for wrapped objects provided by the StdObjSpace."
     # Note that not all wrapped objects in the interpreter inherit from
     # W_Object.  (They inherit from W_Root.)
-    __slots__ = ()
+    _attrs_ = ()
 
     def __repr__(self):
         name = getattr(self, 'name', '')
diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py
--- a/pypy/objspace/std/typeobject.py
+++ b/pypy/objspace/std/typeobject.py
@@ -94,6 +94,7 @@
     _immutable_fields_ = ["flag_heaptype",
                           "flag_cpytype",
                           "flag_abstract?",
+                          'has_del?',
                           'weakrefable',
                           'hasdict',
                           'nslots',
@@ -292,10 +293,6 @@
         if not w_self.is_heaptype():
             msg = "can't set attributes on type object '%s'"
             raise operationerrfmt(space.w_TypeError, msg, w_self.name)
-        if name == "__del__" and name not in w_self.dict_w:
-            msg = ("a __del__ method added to an existing type will not be "
-                   "called")
-            space.warn(space.wrap(msg), space.w_RuntimeWarning)
         if space.config.objspace.std.withtypeversion:
             version_tag = w_self.version_tag()
             if version_tag is not None:
@@ -783,6 +780,7 @@
                 w_self.dict_w['__module__'] = w_name
 
 def compute_mro(w_self):
+    mro_w = None
     if w_self.is_heaptype():
         space = w_self.space
         w_metaclass = space.type(w_self)
@@ -791,9 +789,11 @@
             w_mro_meth = space.get(w_mro_func, w_self)
             w_mro = space.call_function(w_mro_meth)
             mro_w = space.fixedview(w_mro)
-            w_self.mro_w = validate_custom_mro(space, mro_w)
-            return    # done
-    w_self.mro_w = w_self.compute_default_mro()[:]
+            mro_w = validate_custom_mro(space, mro_w)
+    if mro_w is None:
+        mro_w = w_self.compute_default_mro()[:]
+    w_self.mro_w = mro_w
+    w_self.has_del = (w_self.lookup("__del__") is not None)
 
 def validate_custom_mro(space, mro_w):
     # do some checking here.  Note that unlike CPython, strange MROs


More information about the pypy-commit mailing list