[pypy-commit] pypy list-strategies: add a space.newlist_str method that can be used to wrap a list of unwrapped

cfbolz noreply at buildbot.pypy.org
Wed Oct 5 14:05:44 CEST 2011


Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: list-strategies
Changeset: r47832:36b7b2d1a3d8
Date: 2011-10-05 13:59 +0200
http://bitbucket.org/pypy/pypy/changeset/36b7b2d1a3d8/

Log:	add a space.newlist_str method that can be used to wrap a list of
	unwrapped strings. implement a fast path in the std object space.

diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -842,6 +842,9 @@
         """
         return None
 
+    def newlist_str(self, list_s):
+        return self.newlist([self.wrap(s) for s in list_s])
+
     @jit.unroll_safe
     def exception_match(self, w_exc_type, w_check_class):
         """Checks if the given exception type matches 'w_check_class'."""
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
@@ -77,8 +77,16 @@
         w_self.space = space
         w_self.strategy = strategy
         w_self.lstorage = storage
+        if not space.config.objspace.std.withliststrategies:
+            w_self.switch_to_object_strategy()
         return w_self
 
+    @staticmethod
+    def newlist_str(space, list_s):
+        strategy = space.fromcache(StringListStrategy)
+        storage = strategy.erase(list_s)
+        return W_ListObject.from_storage_and_strategy(space, storage, strategy)
+
     def __repr__(w_self):
         """ representation for debugging purposes """
         return "%s(%s, %s)" % (w_self.__class__.__name__, w_self.strategy, w_self.lstorage._x)
@@ -91,6 +99,7 @@
     def switch_to_object_strategy(self):
         list_w = self.getitems()
         self.strategy = self.space.fromcache(ObjectListStrategy)
+        # XXX this is quite indirect
         self.init_from_list_w(list_w)
 
     def _temporarily_as_objects(self):
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -307,6 +307,9 @@
     def newlist(self, list_w):
         return W_ListObject(self, list_w)
 
+    def newlist_str(self, list_s):
+        return W_ListObject.newlist_str(self, list_s)
+
     def newdict(self, module=False, instance=False, classofinstance=None,
                 strdict=False):
         return W_DictMultiObject.allocate_and_init_instance(
diff --git a/pypy/objspace/std/stringobject.py b/pypy/objspace/std/stringobject.py
--- a/pypy/objspace/std/stringobject.py
+++ b/pypy/objspace/std/stringobject.py
@@ -215,7 +215,7 @@
 
 def str_split__String_None_ANY(space, w_self, w_none, w_maxsplit=-1):
     maxsplit = space.int_w(w_maxsplit)
-    res_w = []
+    res = []
     value = w_self._value
     length = len(value)
     i = 0
@@ -238,12 +238,12 @@
             maxsplit -= 1   # NB. if it's already < 0, it stays < 0
 
         # the word is value[i:j]
-        res_w.append(sliced(space, value, i, j, w_self))
+        res.append(value[i:j])
 
         # continue to look from the character following the space after the word
         i = j + 1
 
-    return space.newlist(res_w)
+    return space.newlist_str(res)
 
 def str_split__String_String_ANY(space, w_self, w_by, w_maxsplit=-1):
     maxsplit = space.int_w(w_maxsplit)
@@ -253,20 +253,20 @@
     if bylen == 0:
         raise OperationError(space.w_ValueError, space.wrap("empty separator"))
 
-    res_w = []
+    res = []
     start = 0
     if bylen == 1 and maxsplit < 0:
         # fast path: uses str.rfind(character) and str.count(character)
         by = by[0]    # annotator hack: string -> char
         count = value.count(by)
-        res_w = [None] * (count + 1)
+        res = [None] * (count + 1)
         end = len(value)
         while count >= 0:
             assert end >= 0
             prev = value.rfind(by, 0, end)
             start = prev + 1
             assert start >= 0
-            res_w[count] = sliced(space, value, start, end, w_self)
+            res[count] = value[start:end]
             count -= 1
             end = prev
     else:
@@ -274,12 +274,12 @@
             next = value.find(by, start)
             if next < 0:
                 break
-            res_w.append(sliced(space, value, start, next, w_self))
+            res.append(value[start:next])
             start = next + bylen
             maxsplit -= 1   # NB. if it's already < 0, it stays < 0
-        res_w.append(sliced(space, value, start, len(value), w_self))
+        res.append(value[start:])
 
-    return space.newlist(res_w)
+    return space.newlist_str(res)
 
 def str_rsplit__String_None_ANY(space, w_self, w_none, w_maxsplit=-1):
     maxsplit = space.int_w(w_maxsplit)
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
@@ -360,6 +360,26 @@
         w_l.getitems = None
         assert space.str_w(space.call_method(space.wrap("c"), "join", w_l)) == "acb"
 
+    def test_newlist_str(self):
+        space = self.space
+        l = ['a', 'b']
+        w_l = self.space.newlist_str(l)
+        assert isinstance(w_l.strategy, StringListStrategy)
+        assert space.listview_str(w_l) is l
+
+    def test_string_uses_newlist_str(self):
+        space = self.space
+        w_s = space.wrap("a b c")
+        space.newlist = None
+        try:
+            w_l = space.call_method(w_s, "split")
+            w_l2 = space.call_method(w_s, "split", space.wrap(" "))
+        finally:
+            del space.newlist
+        assert space.listview_str(w_l) == ["a", "b", "c"]
+        assert space.listview_str(w_l2) == ["a", "b", "c"]
+
+
 class TestW_ListStrategiesDisabled:
     def setup_class(cls):
         cls.space = gettestobjspace(**{"objspace.std.withliststrategies" :
diff --git a/pypy/objspace/std/test/test_strsliceobject.py b/pypy/objspace/std/test/test_strsliceobject.py
--- a/pypy/objspace/std/test/test_strsliceobject.py
+++ b/pypy/objspace/std/test/test_strsliceobject.py
@@ -110,12 +110,6 @@
         assert 'W_StringSliceObject' in __pypy__.internal_repr(s)
         assert hash(s) & 0x7fffffff == 0x7e0bce58
 
-    def test_split_produces_strslices(self):
-        import __pypy__
-        l = ("X" * 100 + "," + "Y" * 100).split(",")
-        assert "W_StringSliceObject" in __pypy__.internal_repr(l[0])
-        assert "W_StringSliceObject" in __pypy__.internal_repr(l[1])
-
     def test_strip_produces_strslices(self):
         import __pypy__
         s = ("abc" + "X" * 100 + "," + "Y" * 100 + "abc").strip("abc")


More information about the pypy-commit mailing list