Author: Carl Friedrich Bolz <[email protected]>
Branch: typed-cells
Changeset: r75652:b193ed03acc0
Date: 2015-02-02 18:51 +0100
http://bitbucket.org/pypy/pypy/changeset/b193ed03acc0/

Log:    also unwrap floats

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
@@ -9,7 +9,8 @@
     BaseValueIterator, BaseItemIterator, _never_equal_to_string
 )
 from pypy.objspace.std.typeobject import (
-    MutableCell, IntMutableCell, ObjectMutableCell, unwrap_cell)
+    MutableCell, IntMutableCell, FloatMutableCell, ObjectMutableCell,
+    unwrap_cell)
 
 # ____________________________________________________________
 # attribute shapes
@@ -303,15 +304,24 @@
 
     def _write_cell(self, w_cell, w_value):
         from pypy.objspace.std.intobject import W_IntObject
+        from pypy.objspace.std.floatobject import W_FloatObject
         assert not isinstance(w_cell, ObjectMutableCell)
         if isinstance(w_cell, IntMutableCell) and type(w_value) is W_IntObject:
             w_cell.intvalue = w_value.intval
             return None
+        if isinstance(w_cell, FloatMutableCell) and type(w_value) is 
W_FloatObject:
+            w_cell.floatvalue = w_value.floatval
+            return None
         if type(w_value) is W_IntObject:
             if not self.can_contain_mutable_cell:
                 self.can_contain_mutable_cell = True
             if self.ever_mutated:
                 return IntMutableCell(w_value.intval)
+        if type(w_value) is W_FloatObject:
+            if not self.can_contain_mutable_cell:
+                self.can_contain_mutable_cell = True
+            if self.ever_mutated:
+                return FloatMutableCell(w_value.floatval)
         return w_value
 
     def _copy_attr(self, 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
@@ -182,6 +182,35 @@
     assert mutcell2.intvalue == 7
     assert mutcell2 is mutcell1
 
+
+def test_mutcell_not_immutable_float():
+    from pypy.objspace.std.floatobject import W_FloatObject
+    cls = Class()
+    obj = cls.instantiate()
+    # make sure the attribute counts as mutable
+    obj.setdictvalue(space, "a", W_FloatObject(4.43))
+    obj.setdictvalue(space, "a", W_FloatObject(5.43))
+    assert obj.map.ever_mutated
+
+    obj = cls.instantiate()
+    obj.setdictvalue(space, "a", W_FloatObject(5.43))
+    assert obj.getdictvalue(space, "a") == 5.43
+    mutcell = obj._mapdict_read_storage(0)
+    assert mutcell.floatvalue == 5.43
+
+    obj.setdictvalue(space, "a", W_FloatObject(6.43))
+    assert obj.getdictvalue(space, "a") == 6.43
+    mutcell1 = obj._mapdict_read_storage(0)
+    assert mutcell1.floatvalue == 6.43
+    assert mutcell is mutcell1
+
+    obj.setdictvalue(space, "a", W_FloatObject(7.43))
+    assert obj.getdictvalue(space, "a") == 7.43
+    mutcell2 = obj._mapdict_read_storage(0)
+    assert mutcell2.floatvalue == 7.43
+    assert mutcell2 is mutcell1
+
+
 def test_no_mutcell_if_immutable():
     # don't introduce an immutable cell if the attribute seems immutable
     from pypy.objspace.std.intobject import W_IntObject
diff --git a/pypy/objspace/std/test/test_versionedtype.py 
b/pypy/objspace/std/test/test_versionedtype.py
--- a/pypy/objspace/std/test/test_versionedtype.py
+++ b/pypy/objspace/std/test/test_versionedtype.py
@@ -259,6 +259,43 @@
         cell = w_A._getdictvalue_no_unwrapping(space, "x")
         assert space.float_w(cell.w_value) == 2.2
 
+    def test_float_cells(self):
+        space = self.space
+        w_x = space.wrap("x")
+        w_A, w_B, w_C = self.get_three_classes()
+        atag = w_A.version_tag()
+        space.setattr(w_A, w_x, space.newfloat(1.1))
+        assert w_A.version_tag() is not atag
+        assert space.float_w(space.getattr(w_A, w_x)) == 1.1
+
+        atag = w_A.version_tag()
+        space.setattr(w_A, w_x, space.newfloat(2.1))
+        assert w_A.version_tag() is not atag
+        assert space.float_w(space.getattr(w_A, w_x)) == 2.1
+        cell = w_A._getdictvalue_no_unwrapping(space, "x")
+        assert cell.floatvalue == 2.1
+
+        atag = w_A.version_tag()
+        space.setattr(w_A, w_x, space.newfloat(3.1))
+        assert w_A.version_tag() is atag
+        assert space.float_w(space.getattr(w_A, w_x)) == 3.1
+        assert cell.floatvalue == 3.1
+
+        space.setattr(w_A, w_x, space.newfloat(4.1))
+        assert w_A.version_tag() is atag
+        assert space.float_w(space.getattr(w_A, w_x)) == 4.1
+        assert cell.floatvalue == 4.1
+
+    def test_float_cell_turns_into_cell(self):
+        space = self.space
+        w_x = space.wrap("x")
+        w_A, w_B, w_C = self.get_three_classes()
+        atag = w_A.version_tag()
+        space.setattr(w_A, w_x, space.newfloat(1.1))
+        space.setattr(w_A, w_x, space.newfloat(2.1))
+        space.setattr(w_A, w_x, space.wrap("abc"))
+        cell = w_A._getdictvalue_no_unwrapping(space, "x")
+        assert space.str_w(cell.w_value) == "abc"
 
 
 class AppTestVersionedType(test_typeobject.AppTestTypeObject):
diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py
--- a/pypy/objspace/std/typeobject.py
+++ b/pypy/objspace/std/typeobject.py
@@ -36,6 +36,17 @@
     def __repr__(self):
         return "<IntMutableCell: %s>" % (self.intvalue, )
 
+class FloatMutableCell(MutableCell):
+    def __init__(self, floatvalue):
+        self.floatvalue = floatvalue
+
+    def unwrap_cell(self, space):
+        return space.wrap(self.floatvalue)
+
+    def __repr__(self):
+        return "<FloatMutableCell: %s>" % (self.floatvalue, )
+
+
 def unwrap_cell(space, w_value):
     if isinstance(w_value, MutableCell):
         return w_value.unwrap_cell(space)
@@ -49,6 +60,7 @@
 
 def write_cell(space, w_cell, w_value):
     from pypy.objspace.std.intobject import W_IntObject
+    from pypy.objspace.std.floatobject import W_FloatObject
     if w_cell is None:
         # attribute does not exist at all, write it without a cell first
         return w_value
@@ -58,14 +70,19 @@
     elif isinstance(w_cell, IntMutableCell) and type(w_value) is W_IntObject:
         w_cell.intvalue = w_value.intval
         return None
+    elif isinstance(w_cell, FloatMutableCell) and type(w_value) is 
W_FloatObject:
+        w_cell.floatvalue = w_value.floatval
+        return None
     elif space.is_w(w_cell, w_value):
         # If the new value and the current value are the same, don't
         # create a level of indirection, or mutate the version.
         return None
-    if type(w_value) is W_IntObject:
-        return IntMutableCell(w_value.intval)
-    else:
-        return ObjectMutableCell(w_value)
+    if not isinstance(w_cell, MutableCell):
+        if type(w_value) is W_IntObject:
+            return IntMutableCell(w_value.intval)
+        if type(w_value) is W_FloatObject:
+            return FloatMutableCell(w_value.floatval)
+    return ObjectMutableCell(w_value)
 
 class VersionTag(object):
     pass
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to