[pypy-commit] pypy refactor-wrapped-del: Need to typecheck all callbacks from enqueue_for_destruction().

arigo noreply at buildbot.pypy.org
Tue Jul 12 13:39:51 CEST 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: refactor-wrapped-del
Changeset: r45506:0605e5c98e8a
Date: 2011-07-12 13:23 +0200
http://bitbucket.org/pypy/pypy/changeset/0605e5c98e8a/

Log:	Need to typecheck all callbacks from enqueue_for_destruction().

diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -156,6 +156,9 @@
         At a later, safe point in time, UserDelAction will call
         callback(self).  If that raises OperationError, prints it
         to stderr with the descrname string.
+
+        Note that 'callback' will usually need to start with:
+            assert isinstance(self, W_SpecificClass)
         """
         # this function always resurect the object, so when
         # running on top of CPython we must manually ensure that
diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py
--- a/pypy/interpreter/generator.py
+++ b/pypy/interpreter/generator.py
@@ -114,6 +114,7 @@
  
     def descr_close(self):
         """x.close(arg) -> raise GeneratorExit inside generator."""
+        assert isinstance(self, GeneratorIterator)
         space = self.space
         try:
             w_retval = self.throw(space.w_GeneratorExit, space.w_None,
@@ -144,11 +145,11 @@
     def __del__(self):
         # Only bother enqueuing self to raise an exception if the frame is
         # still not finished and finally or except blocks are present.
-        self.clear_all_weakrefs()
         if self.frame is not None:
             block = self.frame.lastblock
             while block is not None:
                 if not isinstance(block, LoopBlock):
+                    self.clear_all_weakrefs()
                     self.enqueue_for_destruction(self.space,
                                                  GeneratorIterator.descr_close,
                                                  "interrupting generator of ")
diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -234,13 +234,19 @@
 
     if "del" in features:
         parent_destructor = getattr(supercls, '__del__', None)
+        def call_parent_del(self):
+            assert isinstance(self, subcls)
+            parent_destructor(self)
+        def call_applevel_del(self):
+            assert isinstance(self, subcls)
+            self.space.userdel(self)
         class Proto(object):
             def __del__(self):
                 self.clear_all_weakrefs()
                 self.enqueue_for_destruction(self.space, call_applevel_del,
                                              'method __del__ of ')
                 if parent_destructor is not None:
-                    self.enqueue_for_destruction(self.space, parent_destructor,
+                    self.enqueue_for_destruction(self.space, call_parent_del,
                                                  'internal destructor of ')
         add(Proto)
 
@@ -293,9 +299,6 @@
     return w_dict
 check_new_dictionary._dont_inline_ = True
 
-def call_applevel_del(self):
-    self.space.userdel(self)
-
 # ____________________________________________________________
 
 @specialize.arg(0)
diff --git a/pypy/module/_file/interp_file.py b/pypy/module/_file/interp_file.py
--- a/pypy/module/_file/interp_file.py
+++ b/pypy/module/_file/interp_file.py
@@ -52,6 +52,7 @@
                                          'close() method of ')
 
     def report_streamerror(self):
+        assert isinstance(self, W_File)
         operr = wrap_streamerror(self.space, self.streamerror_upon_closing,
                                  self.w_name)
         raise operr
diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py
--- a/pypy/module/_io/interp_iobase.py
+++ b/pypy/module/_io/interp_iobase.py
@@ -61,6 +61,7 @@
                                      'internal __del__ of ')
 
     def destructor(self):
+        assert isinstance(self, W_IOBase)
         space = self.space
         w_closed = space.findattr(self, space.wrap('closed'))
         try:
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
@@ -120,6 +120,7 @@
         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):


More information about the pypy-commit mailing list