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