[pypy-commit] pypy default: Re-add an optimization that was incorrectly implemented and
arigo
noreply at buildbot.pypy.org
Mon Apr 2 11:21:38 CEST 2012
Author: Armin Rigo <arigo at 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):
More information about the pypy-commit
mailing list