[pypy-commit] pypy int-float-list-strategy: lst = [0]; lst += [1.2]

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


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

Log:	lst = [0]; lst += [1.2]

	lst = [0]; lst += [1.2, 3]

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
@@ -1658,6 +1658,11 @@
             assert other is not None
             l += other
             return
+        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.extend(w_other)
+                return
         return self._base_extend_from_list(w_list, w_other)
 
 
@@ -1680,20 +1685,23 @@
         return [longlong2float.encode_int32_into_longlong_nan(intval)
                 for intval in l]
 
+    def switch_to_int_or_float_strategy(self, w_list):
+        try:
+            generalized_list = self.int_2_float_or_int(w_list)
+        except ValueError:
+            return False
+        strategy = self.space.fromcache(IntOrFloatListStrategy)
+        w_list.strategy = strategy
+        w_list.lstorage = strategy.erase(generalized_list)
+        return True
+
     def switch_to_next_strategy(self, w_list, w_sample_item):
         if type(w_sample_item) is W_FloatObject:
-            try:
-                generalized_list = self.int_2_float_or_int(w_list)
-            except ValueError:
-                pass
-            else:
+            if self.switch_to_int_or_float_strategy(w_list):
                 # yes, we can switch to IntOrFloatListStrategy
                 # (ignore here the extremely unlikely case where
                 # w_sample_item is just the wrong nonstandard NaN float;
                 # it will caught later and yet another switch will occur)
-                strategy = self.space.fromcache(IntOrFloatListStrategy)
-                w_list.strategy = strategy
-                w_list.lstorage = strategy.erase(generalized_list)
                 return
         # no, fall back to ObjectListStrategy
         w_list.switch_to_object_strategy()
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
@@ -888,9 +888,27 @@
         assert space.unwrap(w_l1) == [0, 1.2, 3.4]
 
     def test_int_or_float_extend_mixed_3(self):
+        space = self.space
+        w_l1 = W_ListObject(space, [space.wrap(0)])
+        w_l2 = W_ListObject(space, [space.wrap(3.4)])
+        assert isinstance(w_l1.strategy, IntegerListStrategy)
+        assert isinstance(w_l2.strategy, FloatListStrategy)
+        w_l1.extend(w_l2)
+        assert isinstance(w_l1.strategy, IntOrFloatListStrategy)
+        assert space.unwrap(w_l1) == [0, 3.4]
+
+    def test_int_or_float_extend_mixed_4(self):
+        space = self.space
+        w_l1 = W_ListObject(space, [space.wrap(0)])
+        w_l2 = W_ListObject(space, [space.wrap(3.4), space.wrap(-2)])
+        assert isinstance(w_l1.strategy, IntegerListStrategy)
+        assert isinstance(w_l2.strategy, IntOrFloatListStrategy)
+        w_l1.extend(w_l2)
+        assert isinstance(w_l1.strategy, IntOrFloatListStrategy)
+        assert space.unwrap(w_l1) == [0, 3.4, -2]
+
+    def test_int_or_float_extend_mixed_5(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]
 


More information about the pypy-commit mailing list