[pypy-svn] r52119 - in pypy/dist/pypy/module/__builtin__: . test

arigo at codespeak.net arigo at codespeak.net
Mon Mar 3 20:43:49 CET 2008


Author: arigo
Date: Mon Mar  3 20:43:49 2008
New Revision: 52119

Modified:
   pypy/dist/pypy/module/__builtin__/interp_classobj.py
   pypy/dist/pypy/module/__builtin__/test/test_classobj.py
Log:
issue334 testing

Give a RuntimeWarning when attaching a fresh __del__
to an old-style instance.


Modified: pypy/dist/pypy/module/__builtin__/interp_classobj.py
==============================================================================
--- pypy/dist/pypy/module/__builtin__/interp_classobj.py	(original)
+++ pypy/dist/pypy/module/__builtin__/interp_classobj.py	Mon Mar  3 20:43:49 2008
@@ -132,7 +132,7 @@
                 self.setbases(space, w_value)
                 return
             elif name == "__del__":
-                if self.lookup(space, space.wrap('__del__')) is None:
+                if self.lookup(space, w_attr) is None:
                     msg = ("a __del__ method added to an existing class "
                            "will not be called")
                     space.warn(msg, space.w_RuntimeWarning)
@@ -349,32 +349,42 @@
             raise
 
     def descr_setattr(self, space, w_name, w_value):
-        name = space.str_w(w_name)
-        if name == '__dict__':
-            self.setdict(space, w_value)
-        elif name == '__class__':
-            self.setclass(space, w_value)
+        name = unwrap_attr(space, w_name)
+        w_meth = self.getattr(space, space.wrap('__setattr__'), False)
+        if name and name[0] == "_":
+            if name == '__dict__':
+                self.setdict(space, w_value)
+                return
+            if name == '__class__':
+                self.setclass(space, w_value)
+                return
+            if name == '__del__' and w_meth is None:
+                if (not isinstance(self, W_InstanceObjectWithDel)
+                    and space.finditem(self.w_dict, w_name) is None):
+                    msg = ("a __del__ method added to an instance "
+                           "with no __del__ in the class will not be called")
+                    space.warn(msg, space.w_RuntimeWarning)
+        if w_meth is not None:
+            space.call_function(w_meth, w_name, w_value)
         else:
-            w_meth = self.getattr(space, space.wrap('__setattr__'), False)
-            if w_meth is not None:
-                space.call_function(w_meth, w_name, w_value)
-            else:
-                self.setdictvalue(space, w_name, w_value)
+            self.setdictvalue(space, w_name, w_value)
 
     def descr_delattr(self, space, w_name):
-        name = space.str_w(w_name)
-        if name == '__dict__':
-            # use setdict to raise the error
-            self.setdict(space, None)
-        elif name == '__class__':
-            # use setclass to raise the error
-            self.setclass(space, None)
+        name = unwrap_attr(space, w_name)
+        if name and name[0] == "_":
+            if name == '__dict__':
+                # use setdict to raise the error
+                self.setdict(space, None)
+                return
+            elif name == '__class__':
+                # use setclass to raise the error
+                self.setclass(space, None)
+                return
+        w_meth = self.getattr(space, space.wrap('__delattr__'), False)
+        if w_meth is not None:
+            space.call_function(w_meth, w_name)
         else:
-            w_meth = self.getattr(space, space.wrap('__delattr__'), False)
-            if w_meth is not None:
-                space.call_function(w_meth, w_name)
-            else:
-                self.deldictvalue(space, w_name)
+            self.deldictvalue(space, w_name)
 
     def descr_repr(self, space):
         w_meth = self.getattr(space, space.wrap('__repr__'), False)

Modified: pypy/dist/pypy/module/__builtin__/test/test_classobj.py
==============================================================================
--- pypy/dist/pypy/module/__builtin__/test/test_classobj.py	(original)
+++ pypy/dist/pypy/module/__builtin__/test/test_classobj.py	Mon Mar  3 20:43:49 2008
@@ -691,11 +691,18 @@
     def test_assignment_to_del(self):
         import warnings
         
-        class X:
-            pass
-
         warnings.simplefilter('error', RuntimeWarning)
         try:
+            class X:
+                pass
             raises(RuntimeWarning, "X.__del__ = lambda self: None")
+            class Y:
+                pass
+            raises(RuntimeWarning, "Y().__del__ = lambda self: None")
+            # but the following works
+            class Z:
+                def __del__(self):
+                    pass
+            Z().__del__ = lambda self: None
         finally:
             warnings.simplefilter('default', RuntimeWarning)



More information about the Pypy-commit mailing list