Author: Armin Rigo <[email protected]>
Branch: int-float-list-strategy
Changeset: r78403:cadc17f46535
Date: 2015-07-02 10:12 +0200
http://bitbucket.org/pypy/pypy/changeset/cadc17f46535/
Log: lst = [1.2]; lst += [0]
lst = [1.2]; lst += [0, 3.4]
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
@@ -1738,6 +1738,21 @@
def getitems_float(self, w_list):
return self.unerase(w_list.lstorage)
+
+ _base_extend_from_list = _extend_from_list
+
+ def _extend_from_list(self, w_list, w_other):
+ if (w_other.strategy is self.space.fromcache(IntegerListStrategy) or
+ w_other.strategy is self.space.fromcache(IntOrFloatListStrategy)):
+ # xxx a case that we don't optimize: [3.4].extend([9999999999999])
+ # will cause a switch to int-or-float, followed by another
+ # switch to object
+ 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)
+
+
def _safe_find(self, w_list, obj, start, stop):
from rpython.rlib.rfloat import isnan
#
@@ -1766,21 +1781,24 @@
longlong2float.float2longlong(floatval))
return generalized_list
+ def switch_to_int_or_float_strategy(self, w_list):
+ # xxx we should be able to use the same lstorage, but
+ # there is a typing issue (float vs longlong)...
+ try:
+ generalized_list = self.float_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_IntObject:
sample_intval = self.space.int_w(w_sample_item)
if longlong2float.can_encode_int32(sample_intval):
- # xxx we should be able to use the same lstorage, but
- # there is a typing issue (float vs longlong)...
- try:
- generalized_list = self.float_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
- 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
@@ -908,9 +908,37 @@
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 = [1.2]; lst += [0]
- # lst = [1.2]; lst += [0, 3.4]
+ space = self.space
+ w_l1 = W_ListObject(space, [space.wrap(-2.5)])
+ w_l2 = W_ListObject(space, [space.wrap(42)])
+ assert isinstance(w_l1.strategy, FloatListStrategy)
+ assert isinstance(w_l2.strategy, IntegerListStrategy)
+ w_l1.extend(w_l2)
+ assert isinstance(w_l1.strategy, IntOrFloatListStrategy)
+ assert space.unwrap(w_l1) == [-2.5, 42]
+
+ def test_int_or_float_extend_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(-2.5)])
+ w_l2 = W_ListObject(space, [space.wrap(ovf1)])
+ assert isinstance(w_l1.strategy, FloatListStrategy)
+ assert isinstance(w_l2.strategy, IntegerListStrategy)
+ w_l1.extend(w_l2)
+ assert isinstance(w_l1.strategy, ObjectListStrategy)
+ assert space.unwrap(w_l1) == [-2.5, ovf1]
+
+ def test_int_or_float_extend_mixed_6(self):
+ space = self.space
+ w_l1 = W_ListObject(space, [space.wrap(-2.5)])
+ w_l2 = W_ListObject(space, [space.wrap(3.4), space.wrap(-2)])
+ assert isinstance(w_l1.strategy, FloatListStrategy)
+ assert isinstance(w_l2.strategy, IntOrFloatListStrategy)
+ w_l1.extend(w_l2)
+ assert isinstance(w_l1.strategy, IntOrFloatListStrategy)
+ assert space.unwrap(w_l1) == [-2.5, 3.4, -2]
def test_int_or_float_setslice(self):
space = self.space
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit