[pypy-commit] pypy list-strategies: add a new space method listview_str which returns None except if the argument

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


Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: list-strategies
Changeset: r47831:547bc8141987
Date: 2011-10-05 13:29 +0200
http://bitbucket.org/pypy/pypy/changeset/547bc8141987/

Log:	add a new space method listview_str which returns None except if the
	argument is a list using the string strategy. then return an
	unwrapped list of unwrapped strings. use this in str.join.

diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -835,6 +835,13 @@
         """
         return self.unpackiterable(w_iterable, expected_length)
 
+    def listview_str(self, w_list):
+        """ Return a list of unwrapped strings out of a list of strings. If the
+        argument is not a list or does not contain only strings, return None.
+        May return None anyway.
+        """
+        return None
+
     @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
@@ -153,6 +153,11 @@
         """Returns a copy of all items in the list. Same as getitems except for
         ObjectListStrategy."""
         return self.strategy.getitems_copy(self)
+
+    def getitems_str(self):
+        """ Return the items in the list as unwrapped strings. If the list does
+        not use the list strategy, return None. """
+        return self.strategy.getitems_str(self)
     # ___________________________________________________
 
 
@@ -245,6 +250,9 @@
     def getitems_copy(self, w_list):
         raise NotImplementedError
 
+    def getitems_str(self, w_list):
+        return None
+
     def getstorage_copy(self, w_list):
         raise NotImplementedError
 
@@ -923,6 +931,9 @@
         if reverse:
             l.reverse()
 
+    def getitems_str(self, w_list):
+        return self.unerase(w_list.lstorage)
+
 # _______________________________________________________
 
 init_signature = Signature(['sequence'], None, None)
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
@@ -436,6 +436,11 @@
             raise self._wrap_expected_length(expected_length, len(t))
         return t
 
+    def listview_str(self, w_obj):
+        if isinstance(w_obj, W_ListObject):
+            return w_obj.getitems_str()
+        return None
+
     def sliceindices(self, w_slice, w_length):
         if isinstance(w_slice, W_SliceObject):
             a, b, c = w_slice.indices3(self, self.int_w(w_length))
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
@@ -347,6 +347,9 @@
                                                        sliced)
 
 def str_join__String_ANY(space, w_self, w_list):
+    l = space.listview_str(w_list)
+    if l is not None:
+        return space.wrap(w_self._value.join(l))
     list_w = space.listview(w_list)
     size = len(list_w)
 
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
@@ -348,6 +348,17 @@
         l3 = W_ListObject(self.space, [self.space.wrap("eins"), self.space.wrap(u"zwei")])
         assert isinstance(l3.strategy, ObjectListStrategy)
 
+    def test_listview_str(self):
+        space = self.space
+        assert space.listview_str(space.wrap("a")) is None
+        w_l = self.space.newlist([self.space.wrap('a'), self.space.wrap('b')])
+        assert space.listview_str(w_l) == ["a", "b"]
+
+    def test_string_uses_listview_str(self):
+        space = self.space
+        w_l = self.space.newlist([self.space.wrap('a'), self.space.wrap('b')])
+        w_l.getitems = None
+        assert space.str_w(space.call_method(space.wrap("c"), "join", w_l)) == "acb"
 
 class TestW_ListStrategiesDisabled:
     def setup_class(cls):


More information about the pypy-commit mailing list