Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r54145:4767e4614bfa Date: 2012-04-02 11:20 +0200 http://bitbucket.org/pypy/pypy/changeset/4767e4614bfa/
Log: Re-add an optimization that was incorrectly implemented and so killed by the merge of list strategies. diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -43,6 +43,13 @@ return w_eq type_eq._annspecialcase_ = 'specialize:memo' +def list_iter(space): + "Utility that returns the app-level descriptor list.__iter__." + w_src, w_iter = space.lookup_in_type_where(space.w_list, + '__iter__') + return w_iter +list_iter._annspecialcase_ = 'specialize:memo' + def raiseattrerror(space, w_obj, name, w_descr=None): w_type = space.type(w_obj) typename = w_type.getname(space) 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 @@ -439,6 +439,8 @@ t = w_obj.getitems() elif isinstance(w_obj, W_AbstractTupleObject): t = w_obj.getitems_copy() + elif isinstance(w_obj, W_ListObject) and self._uses_list_iter(w_obj): + t = w_obj.getitems() else: return ObjSpace.unpackiterable(self, w_obj, expected_length) if expected_length != -1 and len(t) != expected_length: @@ -456,6 +458,8 @@ return w_obj.listview_str() if isinstance(w_obj, W_StringObject): return w_obj.listview_str() + if isinstance(w_obj, W_ListObject) and self._uses_list_iter(w_obj): + return w_obj.getitems_str() return None def listview_int(self, w_obj): @@ -465,8 +469,14 @@ return w_obj.listview_int() if type(w_obj) is W_SetObject or type(w_obj) is W_FrozensetObject: return w_obj.listview_int() + if isinstance(w_obj, W_ListObject) and self._uses_list_iter(w_obj): + return w_obj.getitems_int() return None + def _uses_list_iter(self, w_obj): + from pypy.objspace.descroperation import list_iter + return self.lookup(w_obj, '__iter__') is list_iter(self) + 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/test/test_listobject.py b/pypy/objspace/std/test/test_listobject.py --- a/pypy/objspace/std/test/test_listobject.py +++ b/pypy/objspace/std/test/test_listobject.py @@ -1186,14 +1186,23 @@ # of dicts, because the OrderedDict in the stdlib relies on this. # we extend the use case to lists and sets, i.e. all types that have # strategies, to avoid surprizes depending on the strategy. - for base, arg in [(list, []), (list, [5]), (list, ['x']), - (set, []), (set, [5]), (set, ['x']), - (dict, []), (dict, [(5,6)]), (dict, [('x',7)])]: + class X: pass + for base, arg in [ + (list, []), (list, [5]), (list, ['x']), (list, [X]), + (set, []), (set, [5]), (set, ['x']), (set, [X]), + (dict, []), (dict, [(5,6)]), (dict, [('x',7)]), (dict, [(X,8)]), + ]: print base, arg class SubClass(base): def __iter__(self): return iter("foobar") assert list(SubClass(arg)) == ['f', 'o', 'o', 'b', 'a', 'r'] + class Sub2(base): + pass + assert list(Sub2(arg)) == list(base(arg)) + s = set() + s.update(Sub2(arg)) + assert s == set(base(arg)) class AppTestForRangeLists(AppTestW_ListObject): _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit