Author: Armin Rigo <[email protected]>
Branch: gc-del
Changeset: r66063:e3628e64912d
Date: 2013-08-10 20:00 +0200
http://bitbucket.org/pypy/pypy/changeset/e3628e64912d/

Log:    Fix the case of objects with mapdict, which overrides a number of
        methods from typedef.

diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -167,6 +167,14 @@
     def invoke_finalizer(self):
         raise NotImplementedError    # must be overridden
 
+    def _finalizer_perform_del(self, space):
+        """Invoke the app-level __del__."""
+        w_descr = space.lookup(self, '__del__')
+        if w_descr is not None:
+            self.finalizer_perform(space, "__del__ method of ",
+                                   space.get_and_call_function,
+                                   w_descr, self)
+
     def finalizer_perform(self, space, descrname, callback, *args):
         """For use in invoke_finalizer().  First check if we're called
         from the random execution of a __del__ or from UserDelAction,
diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -247,12 +247,7 @@
                     self.register_finalizer()
 
             def invoke_finalizer(self):
-                space = self.space
-                w_descr = space.lookup(self, '__del__')
-                if w_descr is not None:
-                    self.finalizer_perform(self.space, "__del__ method of ",
-                                           space.get_and_call_function,
-                                           w_descr, self)
+                self._finalizer_perform_del(self.space)
                 super_invoke_finalizer(self)
 
             def user_setup_slots(self, nslots):
diff --git a/pypy/objspace/std/mapdict.py b/pypy/objspace/std/mapdict.py
--- a/pypy/objspace/std/mapdict.py
+++ b/pypy/objspace/std/mapdict.py
@@ -415,6 +415,12 @@
         assert (not self.typedef.hasdict or
                 self.typedef is W_InstanceObject.typedef)
         self._init_empty(w_subtype.terminator)
+        if w_subtype.has_del:
+            self.register_finalizer()
+
+    def invoke_finalizer(self):
+        self._finalizer_perform_del(self.space)
+        self._super_invoke_finalizer()
 
     def getslotvalue(self, index):
         key = ("slot", SLOTS_STARTING_FROM + index)
@@ -517,7 +523,12 @@
     rangen = unroll.unrolling_iterable(range(n))
     nmin1 = n - 1
     rangenmin1 = unroll.unrolling_iterable(range(nmin1))
+
     class subcls(BaseMapdictObject, supercls):
+        _super_invoke_finalizer = supercls.invoke_finalizer.im_func
+        if _super_invoke_finalizer == W_Root.invoke_finalizer.im_func:
+            _super_invoke_finalizer = lambda self: None
+
         def _init_empty(self, map):
             from rpython.rlib.debug import make_sure_not_resized
             for i in rangen:
diff --git a/pypy/objspace/std/test/test_mapdict.py 
b/pypy/objspace/std/test/test_mapdict.py
--- a/pypy/objspace/std/test/test_mapdict.py
+++ b/pypy/objspace/std/test/test_mapdict.py
@@ -14,6 +14,7 @@
 space.config = Config
 
 class Class(object):
+    has_del = False
     def __init__(self, hasdict=True):
         self.hasdict = True
         if hasdict:
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to