[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