Author: Carl Friedrich Bolz <cfb...@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") _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit