[pypy-commit] pypy int-float-list-strategy: setslice() support and clean-ups

arigo noreply at buildbot.pypy.org
Thu Jul 2 10:35:45 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: int-float-list-strategy
Changeset: r78404:ecfee265b225
Date: 2015-07-02 10:35 +0200
http://bitbucket.org/pypy/pypy/changeset/ecfee265b225/

Log:	setslice() support and clean-ups

diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -1673,11 +1673,17 @@
             storage = self.erase(w_other.getitems_int())
             w_other = W_ListObject.from_storage_and_strategy(
                     self.space, storage, self)
+        if (w_other.strategy is self.space.fromcache(FloatListStrategy) or
+            w_other.strategy is self.space.fromcache(IntOrFloatListStrategy)):
+            if self.switch_to_int_or_float_strategy(w_list):
+                w_list.setslice(start, step, slicelength, w_other)
+                return
         return self._base_setslice(w_list, start, step, slicelength, w_other)
 
 
-    def int_2_float_or_int(self, w_list):
-        l = self.unerase(w_list.lstorage)
+    @staticmethod
+    def int_2_float_or_int(w_list):
+        l = IntegerListStrategy.unerase(w_list.lstorage)
         if not longlong2float.CAN_ALWAYS_ENCODE_INT32:
             for intval in l:
                 if not longlong2float.can_encode_int32(intval):
@@ -1753,6 +1759,17 @@
         return self._base_extend_from_list(w_list, w_other)
 
 
+    _base_setslice = setslice
+
+    def setslice(self, w_list, start, step, slicelength, w_other):
+        if (w_other.strategy is self.space.fromcache(IntegerListStrategy) or
+            w_other.strategy is self.space.fromcache(IntOrFloatListStrategy)):
+            if self.switch_to_int_or_float_strategy(w_list):
+                w_list.setslice(start, step, slicelength, w_other)
+                return
+        return self._base_setslice(w_list, start, step, slicelength, w_other)
+
+
     def _safe_find(self, w_list, obj, start, stop):
         from rpython.rlib.rfloat import isnan
         #
@@ -1771,8 +1788,9 @@
                     return i
         raise ValueError
 
-    def float_2_float_or_int(self, w_list):
-        l = self.unerase(w_list.lstorage)
+    @staticmethod
+    def float_2_float_or_int(w_list):
+        l = FloatListStrategy.unerase(w_list.lstorage)
         generalized_list = []
         for floatval in l:
             if not longlong2float.can_encode_float(floatval):
@@ -1862,20 +1880,43 @@
     def _extend_from_list(self, w_list, w_other):
         if w_other.strategy is self.space.fromcache(IntegerListStrategy):
             try:
-                longlong_list = w_other.strategy.int_2_float_or_int(w_other)
+                longlong_list = IntegerListStrategy.int_2_float_or_int(w_other)
             except ValueError:
                 pass
             else:
                 return self._extend_longlong(w_list, longlong_list)
         if w_other.strategy is self.space.fromcache(FloatListStrategy):
             try:
-                longlong_list = w_other.strategy.float_2_float_or_int(w_other)
+                longlong_list = FloatListStrategy.float_2_float_or_int(w_other)
             except ValueError:
                 pass
             else:
                 return self._extend_longlong(w_list, longlong_list)
         return self._base_extend_from_list(w_list, w_other)
 
+    _base_setslice = setslice
+
+    def _temporary_longlong_list(self, longlong_list):
+        storage = self.erase(longlong_list)
+        return W_ListObject.from_storage_and_strategy(self.space, storage, self)
+
+    def setslice(self, w_list, start, step, slicelength, w_other):
+        if w_other.strategy is self.space.fromcache(IntegerListStrategy):
+            try:
+                longlong_list = IntegerListStrategy.int_2_float_or_int(w_other)
+            except ValueError:
+                pass
+            else:
+                w_other = self._temporary_longlong_list(longlong_list)
+        elif w_other.strategy is self.space.fromcache(FloatListStrategy):
+            try:
+                longlong_list = FloatListStrategy.float_2_float_or_int(w_other)
+            except ValueError:
+                pass
+            else:
+                w_other = self._temporary_longlong_list(longlong_list)
+        return self._base_setslice(w_list, start, step, slicelength, w_other)
+
 
 class BytesListStrategy(ListStrategy):
     import_from_mixin(AbstractUnwrappedStrategy)
diff --git a/pypy/objspace/std/test/test_liststrategies.py b/pypy/objspace/std/test/test_liststrategies.py
--- a/pypy/objspace/std/test/test_liststrategies.py
+++ b/pypy/objspace/std/test/test_liststrategies.py
@@ -318,7 +318,7 @@
 
         l = W_ListObject(space, [w(1.1), w(2.2), w(3.3)])
         assert isinstance(l.strategy, FloatListStrategy)
-        l.extend(W_ListObject(space, [w(4), w(5), w(6)]))
+        l.extend(W_ListObject(space, [w("abc"), w("def"), w("ghi")]))
         assert isinstance(l.strategy, ObjectListStrategy)
 
     def test_empty_extend_with_any(self):
@@ -950,14 +950,78 @@
         assert isinstance(w_l1.strategy, IntOrFloatListStrategy)
         assert space.unwrap(w_l1) == [3, 4.5, 1.2]
 
-    def test_int_or_float_setslice_mixed(self):
-        py.test.skip("XXX not implemented")
-        # lst = [0]; lst[:] = [1.2]
-        # lst = [0]; lst[:] = [1.2, 3]
-        # lst = [1.2]; lst[:] = [0]
-        # lst = [1.2]; lst[:] = [0, 3.4]
-        # lst = [0, 1.2]; lst[:] = [3]
-        # lst = [0, 1.2]; lst[:] = [3.4]
+    def test_int_or_float_setslice_mixed_1(self):
+        space = self.space
+        w_l1 = W_ListObject(space, [space.wrap(0), space.wrap(12)])
+        w_l2 = W_ListObject(space, [space.wrap(3.2), space.wrap(4.5)])
+        assert isinstance(w_l1.strategy, IntegerListStrategy)
+        assert isinstance(w_l2.strategy, FloatListStrategy)
+        w_l1.setslice(0, 1, 1, w_l2)
+        assert isinstance(w_l1.strategy, IntOrFloatListStrategy)
+        assert space.unwrap(w_l1) == [3.2, 4.5, 12]
+
+    def test_int_or_float_setslice_mixed_2(self):
+        space = self.space
+        w_l1 = W_ListObject(space, [space.wrap(0), space.wrap(12)])
+        w_l2 = W_ListObject(space, [space.wrap(3.2), space.wrap(45)])
+        assert isinstance(w_l1.strategy, IntegerListStrategy)
+        assert isinstance(w_l2.strategy, IntOrFloatListStrategy)
+        w_l1.setslice(0, 1, 1, w_l2)
+        assert isinstance(w_l1.strategy, IntOrFloatListStrategy)
+        assert space.unwrap(w_l1) == [3.2, 45, 12]
+
+    def test_int_or_float_setslice_mixed_3(self):
+        space = self.space
+        w_l1 = W_ListObject(space, [space.wrap(0.1), space.wrap(1.2)])
+        w_l2 = W_ListObject(space, [space.wrap(32), space.wrap(45)])
+        assert isinstance(w_l1.strategy, FloatListStrategy)
+        assert isinstance(w_l2.strategy, IntegerListStrategy)
+        w_l1.setslice(0, 1, 1, w_l2)
+        assert isinstance(w_l1.strategy, IntOrFloatListStrategy)
+        assert space.unwrap(w_l1) == [32, 45, 1.2]
+
+    def test_int_or_float_setslice_mixed_4(self):
+        space = self.space
+        w_l1 = W_ListObject(space, [space.wrap(0.1), space.wrap(1.2)])
+        w_l2 = W_ListObject(space, [space.wrap(3.2), space.wrap(45)])
+        assert isinstance(w_l1.strategy, FloatListStrategy)
+        assert isinstance(w_l2.strategy, IntOrFloatListStrategy)
+        w_l1.setslice(0, 1, 1, w_l2)
+        assert isinstance(w_l1.strategy, IntOrFloatListStrategy)
+        assert space.unwrap(w_l1) == [3.2, 45, 1.2]
+
+    def test_int_or_float_setslice_mixed_5(self):
+        space = self.space
+        w_l1 = W_ListObject(space, [space.wrap(0), space.wrap(1.2)])
+        w_l2 = W_ListObject(space, [space.wrap(32), space.wrap(45)])
+        assert isinstance(w_l1.strategy, IntOrFloatListStrategy)
+        assert isinstance(w_l2.strategy, IntegerListStrategy)
+        w_l1.setslice(0, 1, 1, w_l2)
+        assert isinstance(w_l1.strategy, IntOrFloatListStrategy)
+        assert space.unwrap(w_l1) == [32, 45, 1.2]
+
+    def test_int_or_float_setslice_mixed_5_overflow(self):
+        if sys.maxint == 2147483647:
+            py.test.skip("only on 64-bit")
+        space = self.space
+        ovf1 = 2 ** 35
+        w_l1 = W_ListObject(space, [space.wrap(0), space.wrap(1.2)])
+        w_l2 = W_ListObject(space, [space.wrap(32), space.wrap(ovf1)])
+        assert isinstance(w_l1.strategy, IntOrFloatListStrategy)
+        assert isinstance(w_l2.strategy, IntegerListStrategy)
+        w_l1.setslice(0, 1, 1, w_l2)
+        assert isinstance(w_l1.strategy, ObjectListStrategy)
+        assert space.unwrap(w_l1) == [32, ovf1, 1.2]
+
+    def test_int_or_float_setslice_mixed_6(self):
+        space = self.space
+        w_l1 = W_ListObject(space, [space.wrap(0), space.wrap(1.2)])
+        w_l2 = W_ListObject(space, [space.wrap(3.2), space.wrap(4.5)])
+        assert isinstance(w_l1.strategy, IntOrFloatListStrategy)
+        assert isinstance(w_l2.strategy, FloatListStrategy)
+        w_l1.setslice(0, 1, 1, w_l2)
+        assert isinstance(w_l1.strategy, IntOrFloatListStrategy)
+        assert space.unwrap(w_l1) == [3.2, 4.5, 1.2]
 
     def test_int_or_float_sort(self):
         space = self.space


More information about the pypy-commit mailing list