[pypy-commit] pypy type-specialized-instances: added tests and fixes for overwriting attributes with another type and for untaggable ints

l.diekmann noreply at buildbot.pypy.org
Tue Nov 22 16:10:50 CET 2011


Author: Lukas Diekmann <lukas.diekmann at uni-duesseldorf.de>
Branch: type-specialized-instances
Changeset: r49664:c31774e1542e
Date: 2011-11-22 16:10 +0100
http://bitbucket.org/pypy/pypy/changeset/c31774e1542e/

Log:	added tests and fixes for overwriting attributes with another type
	and for untaggable ints

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
@@ -35,10 +35,16 @@
         return attr.read_attr(obj) #obj._mapdict_read_storage(index)
 
     def write(self, obj, selector, w_value):
+        from pypy.interpreter.error import OperationError
         attr = self.findmap(selector) # index = self.index(selector)
         if attr is None:
             return self.terminator._write_terminator(obj, selector, w_value)
-        attr.write_attr(obj, w_value) #obj._mapdict_write_storage(index, w_value)
+        try:
+            attr.write_attr(obj, w_value) #obj._mapdict_write_storage(index, w_value)
+        except OperationError:
+            firstattr = obj.map
+            firstattr.delete(obj, selector)
+            firstattr.add_attr(obj, selector, w_value)
         return True
 
     def delete(self, obj, selector):
@@ -355,13 +361,20 @@
         erased = self.erase_item(self.space.int_w(w_value))
         obj._mapdict_write_storage(self.position, erased)
 
+def is_taggable_int(space, w_value):
+    from pypy.objspace.std.intobject import W_IntObject
+    if type(w_value) is W_IntObject:
+        try:
+            IntAttribute.erase_item(space.int_w(w_value))
+            return True
+        except OverflowError:
+            pass
+    return False
+
 def get_attrclass_from_value(space, w_value):
     attrclass = PlainAttribute
-    try:
-        if space.is_w(space.type(w_value), space.w_int):
-            attrclass = IntAttribute
-    except AttributeError:
-        pass
+    if is_taggable_int(space, w_value):
+        attrclass = IntAttribute
     return attrclass
 
 def _become(w_obj, new_obj):
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
@@ -365,6 +365,51 @@
         assert isinstance(obj1.map, PlainAttribute)
         assert space.eq_w(obj1.getdictvalue(space, "y"), space.wrap("str"))
 
+    def test_overwrite_attribute_with_another_type(self):
+        space = self.space
+        cls = Class(sp=space)
+        obj1 = cls.instantiate()
+
+        obj1.setdictvalue(space, "x", space.wrap(1))
+        assert isinstance(obj1.map, IntAttribute)
+        assert space.eq_w(obj1.getdictvalue(space, "x"), space.wrap(1))
+
+        obj1.setdictvalue(space, "x", space.wrap("a"))
+        assert isinstance(obj1.map, PlainAttribute)
+        assert space.eq_w(obj1.getdictvalue(space, "x"), space.wrap("a"))
+
+    def test_overwrite_attribute_with_another_type2(self):
+        space = self.space
+        cls = Class(sp=space)
+        obj1 = cls.instantiate()
+
+        obj1.setdictvalue(space, "x", space.wrap(1))
+        assert isinstance(obj1.map, IntAttribute)
+        assert space.eq_w(obj1.getdictvalue(space, "x"), space.wrap(1))
+
+        obj1.setdictvalue(space, "y", space.wrap(2))
+        assert isinstance(obj1.map.back, IntAttribute)
+        assert space.eq_w(obj1.getdictvalue(space, "y"), space.wrap(2))
+
+        # overwrite 'x' with new type
+        obj1.setdictvalue(space, "x", space.wrap("a"))
+        assert isinstance(obj1.map, PlainAttribute)
+        assert space.eq_w(obj1.getdictvalue(space, "x"), space.wrap("a"))
+
+        # check if 'y' is still reachable
+        assert isinstance(obj1.map.back, IntAttribute)
+        assert space.eq_w(obj1.getdictvalue(space, "y"), space.wrap(2))
+
+    def test_int_does_not_fit(self):
+        import sys
+        space = self.space
+        cls = Class(sp=space)
+        obj1 = cls.instantiate()
+
+        obj1.setdictvalue(space, "x", space.wrap(sys.maxint))
+        assert isinstance(obj1.map, PlainAttribute)
+        assert space.eq_w(obj1.getdictvalue(space, "x"), space.wrap(sys.maxint))
+
 # ___________________________________________________________
 # dict tests
 


More information about the pypy-commit mailing list