[pypy-svn] r69752 - in pypy/trunk/pypy/objspace/std: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Mon Nov 30 11:51:14 CET 2009


Author: cfbolz
Date: Mon Nov 30 11:51:13 2009
New Revision: 69752

Modified:
   pypy/trunk/pypy/objspace/std/inlinedict.py
   pypy/trunk/pypy/objspace/std/test/test_inlinedict.py
Log:
Fix the bug Maciej found. It was not about slots at all, but the old .__dict__
that was at some point being read out of an object no longer being valid if
.__dict__ is written to. Kill the apptest and write a unit-test for the problem.


Modified: pypy/trunk/pypy/objspace/std/inlinedict.py
==============================================================================
--- pypy/trunk/pypy/objspace/std/inlinedict.py	(original)
+++ pypy/trunk/pypy/objspace/std/inlinedict.py	Mon Nov 30 11:51:13 2009
@@ -118,6 +118,10 @@
             return True
 
         def setdict(self, space, w_dict):
+            # if somebody asked for the __dict__, and it did not devolve, it
+            # needs to stay valid even if we set a new __dict__ on this object
+            if self.w__dict__ is not None and self._inlined_dict_valid():
+                make_rdict(self)
             self._clear_fields() # invalidate attributes on self
             self.w__dict__ = check_new_dictionary(space, w_dict)
 

Modified: pypy/trunk/pypy/objspace/std/test/test_inlinedict.py
==============================================================================
--- pypy/trunk/pypy/objspace/std/test/test_inlinedict.py	(original)
+++ pypy/trunk/pypy/objspace/std/test/test_inlinedict.py	Mon Nov 30 11:51:13 2009
@@ -56,6 +56,21 @@
         w_dict1 = obj1.getdict()
         obj2 = self.make_obj()
         w_dict2 = obj2.getdict()
+        obj2.setdict(self.space, w_dict1)
+        assert obj2.getdictvalue(self.fakespace, "hello") == 1
+        assert obj2.getdictvalue(self.fakespace, "world") == 2
+        obj1.setdictvalue(self.fakespace, "hello", 4)
+        obj1.setdictvalue(self.fakespace, "world", 5)
+        assert obj2.getdictvalue(self.fakespace, "hello") == 4
+        assert obj2.getdictvalue(self.fakespace, "world") == 5
+        assert w_dict2.getitem("hello") == 1
+        assert w_dict2.getitem("world") == 2
+
+    def test_setdict_devolves_existing_dict(self):
+        obj1 = self.make_obj()
+        w_dict1 = obj1.getdict()
+        obj2 = self.make_obj()
+        w_dict2 = obj2.getdict()
         w_dict2.setitem(4, 1) # devolve dict
         w_dict2.setitem(5, 2)
         obj2.setdict(self.space, w_dict1)
@@ -67,6 +82,7 @@
         assert obj2.getdictvalue(self.fakespace, "world") == 5
 
 
+
     def test_dict_devolves_via_dict(self):
         obj = self.make_obj()
         w_dict = obj.getdict()
@@ -82,6 +98,7 @@
         obj.deldictvalue(self.fakespace, "hello")
         assert obj.getdictvalue(self.fakespace, "hello") is None
 
+
 class TestMixinShared(TestMixin):
     Mixin = make_inlinedict_mixin(SharedDictImplementation, "structure")
     class FakeObject(Mixin):
@@ -125,22 +142,3 @@
         assert w_a.w__dict__ is None
         assert self.space.int_w(w_a.content['x']) == 12
         assert self.space.int_w(w_a.content['y']) == 13
-
-class AppTestSharingDict(object):
-    def setup_class(cls):
-        cls.space = gettestobjspace(withsharingdict=True, withinlineddict=True)
-
-    @py.test.mark.xfail()
-    def test_bug(self):
-        class X(object):
-            __slots__ = 'a', 'b', 'c'
-
-        class Y(X):
-            def __setattr__(self, name, value):                
-                d = object.__getattribute__(self, '__dict__')
-                object.__setattr__(self, '__dict__', d)
-                return object.__setattr__(self, name, value)
-
-        x = Y()
-        x.number = 42
-        assert x.number == 42



More information about the Pypy-commit mailing list