Author: Philip Jenvey <[email protected]>
Branch: length-hint
Changeset: r57625:56e278ef5eb1
Date: 2012-09-26 17:02 -0700
http://bitbucket.org/pypy/pypy/changeset/56e278ef5eb1/
Log: add the rest of the needed __length_hint__ impls and more tests
diff --git a/pypy/module/_collections/interp_deque.py
b/pypy/module/_collections/interp_deque.py
--- a/pypy/module/_collections/interp_deque.py
+++ b/pypy/module/_collections/interp_deque.py
@@ -517,6 +517,9 @@
def iter(self):
return self.space.wrap(self)
+ def length(self):
+ return self.space.wrap(self.counter)
+
def next(self):
self.deque.checklock(self.lock)
if self.counter == 0:
@@ -532,8 +535,9 @@
return w_x
W_DequeIter.typedef = TypeDef("deque_iterator",
- __iter__ = interp2app(W_DequeIter.iter),
- next = interp2app(W_DequeIter.next),
+ __iter__ = interp2app(W_DequeIter.iter),
+ __length_hint__ = interp2app(W_DequeIter.length),
+ next = interp2app(W_DequeIter.next),
)
W_DequeIter.typedef.acceptable_as_base_class = False
@@ -552,6 +556,9 @@
def iter(self):
return self.space.wrap(self)
+ def length(self):
+ return self.space.wrap(self.counter)
+
def next(self):
self.deque.checklock(self.lock)
if self.counter == 0:
@@ -567,8 +574,9 @@
return w_x
W_DequeRevIter.typedef = TypeDef("deque_reverse_iterator",
- __iter__ = interp2app(W_DequeRevIter.iter),
- next = interp2app(W_DequeRevIter.next),
+ __iter__ = interp2app(W_DequeRevIter.iter),
+ __length_hint__ = interp2app(W_DequeRevIter.length),
+ next = interp2app(W_DequeRevIter.next),
)
W_DequeRevIter.typedef.acceptable_as_base_class = False
diff --git a/pypy/module/itertools/interp_itertools.py
b/pypy/module/itertools/interp_itertools.py
--- a/pypy/module/itertools/interp_itertools.py
+++ b/pypy/module/itertools/interp_itertools.py
@@ -104,6 +104,11 @@
def iter_w(self):
return self.space.wrap(self)
+ def length_w(self):
+ if not self.counting:
+ return self.space.w_NotImplemented
+ return self.space.wrap(self.count)
+
def repr_w(self):
objrepr = self.space.str_w(self.space.repr(self.w_obj))
if self.counting:
@@ -120,10 +125,11 @@
W_Repeat.typedef = TypeDef(
'repeat',
__module__ = 'itertools',
- __new__ = interp2app(W_Repeat___new__),
- __iter__ = interp2app(W_Repeat.iter_w),
- next = interp2app(W_Repeat.next_w),
- __repr__ = interp2app(W_Repeat.repr_w),
+ __new__ = interp2app(W_Repeat___new__),
+ __iter__ = interp2app(W_Repeat.iter_w),
+ __length_hint__ = interp2app(W_Repeat.length_w),
+ next = interp2app(W_Repeat.next_w),
+ __repr__ = interp2app(W_Repeat.repr_w),
__doc__ = """Make an iterator that returns object over and over again.
Runs indefinitely unless the times argument is specified. Used
as argument to imap() for invariant parameters to the called
diff --git a/pypy/objspace/std/dicttype.py b/pypy/objspace/std/dicttype.py
--- a/pypy/objspace/std/dicttype.py
+++ b/pypy/objspace/std/dicttype.py
@@ -139,6 +139,12 @@
# ____________________________________________________________
+def descr_dictiter__length_hint__(space, w_self):
+ from pypy.objspace.std.dictmultiobject import W_BaseDictMultiIterObject
+ assert isinstance(w_self, W_BaseDictMultiIterObject)
+ return space.wrap(w_self.iteratorimplementation.length())
+
+
def descr_dictiter__reduce__(w_self, space):
"""
This is a slightly special case of pickling.
@@ -195,7 +201,8 @@
dictiter_typedef = StdTypeDef("dictionaryiterator",
- __reduce__ = gateway.interp2app(descr_dictiter__reduce__),
+ __length_hint__ = gateway.interp2app(descr_dictiter__length_hint__),
+ __reduce__ = gateway.interp2app(descr_dictiter__reduce__),
)
# ____________________________________________________________
diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py
--- a/pypy/objspace/std/setobject.py
+++ b/pypy/objspace/std/setobject.py
@@ -900,13 +900,6 @@
return w_key
raise OperationError(space.w_StopIteration, space.w_None)
-# XXX __length_hint__()
-##def len__SetIterObject(space, w_setiter):
-## content = w_setiter.content
-## if content is None or w_setiter.len == -1:
-## return space.wrap(0)
-## return space.wrap(w_setiter.len - w_setiter.pos)
-
# some helper functions
def newset(space):
diff --git a/pypy/objspace/std/settype.py b/pypy/objspace/std/settype.py
--- a/pypy/objspace/std/settype.py
+++ b/pypy/objspace/std/settype.py
@@ -81,4 +81,11 @@
set_typedef.registermethods(globals())
-setiter_typedef = StdTypeDef("setiterator")
+def descr_setiterator__length_hint__(space, w_self):
+ from pypy.objspace.std.setobject import W_SetIterObject
+ assert isinstance(w_self, W_SetIterObject)
+ return space.wrap(w_self.iterimplementation.length())
+
+setiter_typedef = StdTypeDef("setiterator",
+ __length_hint__ = gateway.interp2app(descr_setiterator__length_hint__),
+ )
diff --git a/pypy/objspace/std/test/test_lengthhint.py
b/pypy/objspace/std/test/test_lengthhint.py
--- a/pypy/objspace/std/test/test_lengthhint.py
+++ b/pypy/objspace/std/test/test_lengthhint.py
@@ -1,3 +1,6 @@
+from pypy.module._collections.interp_deque import W_Deque
+from pypy.module.itertools.interp_itertools import W_Repeat
+
class TestLengthHint:
SIZE = 4
@@ -15,8 +18,48 @@
space.next(w_iter)
assert space.length_hint(w_iter, 8) == self.SIZE - 1
+ def test_bytearray(self):
+ space = self.space
+ w_bytearray = space.call_function(space.w_bytearray,
+ space.wrap(self.ITEMS))
+ self._test_length_hint(w_bytearray)
+
+ def test_dict(self):
+ space = self.space
+ w_dict = space.call_function(space.w_dict,
+ space.wrap((i, None) for i in self.ITEMS))
+ self._test_length_hint(w_dict)
+
+ def test_dict_iterkeys(self):
+ w_iterkeys = self.space.appexec([], """():
+ return dict.fromkeys(%r).iterkeys()
+ """ % self.ITEMS)
+ self._test_length_hint(w_iterkeys)
+
+ def test_dict_values(self):
+ w_itervalues = self.space.appexec([], """():
+ return dict.fromkeys(%r).itervalues()
+ """ % self.ITEMS)
+ self._test_length_hint(w_itervalues)
+
+ def test_frozenset(self):
+ space = self.space
+ w_set = space.call_function(space.w_frozenset, space.wrap(self.ITEMS))
+ self._test_length_hint(w_set)
+
+ def test_set(self):
+ space = self.space
+ w_set = space.call_function(space.w_set, space.wrap(self.ITEMS))
+ self._test_length_hint(w_set)
+
def test_list(self):
- self._test_length_hint(self.space.newlist(self.ITEMS))
+ self._test_length_hint(self.space.wrap(self.ITEMS))
+
+ def test_str(self):
+ self._test_length_hint(self.space.wrap('P' * self.SIZE))
+
+ def test_unicode(self):
+ self._test_length_hint(self.space.wrap(u'Y' * self.SIZE))
def test_tuple(self):
self._test_length_hint(self.space.newtuple(self.ITEMS))
@@ -24,7 +67,7 @@
def test_reversed(self):
space = self.space
w_reversed = space.call_method(space.builtin, 'reversed',
- space.newlist(self.ITEMS))
+ space.wrap(self.ITEMS))
assert space.int_w(
space.call_method(w_reversed, '__length_hint__')) == self.SIZE
self._test_length_hint(w_reversed)
@@ -35,12 +78,23 @@
space.newint(self.SIZE))
self._test_length_hint(w_xrange)
+ def test_itertools_repeat(self):
+ space = self.space
+ self._test_length_hint(W_Repeat(space, space.wrap(22),
+ space.wrap(self.SIZE)))
+
+ def test_collections_deque(self):
+ space = self.space
+ w_deque = W_Deque(space)
+ space.call_method(w_deque, '__init__', space.wrap(self.ITEMS))
+ self._test_length_hint(w_deque)
+ self._test_length_hint(w_deque.reviter())
+
def test_default(self):
space = self.space
assert space.length_hint(space.w_False, 3) == 3
def test_NotImplemented(self):
- from pypy.interpreter.error import OperationError
space = self.space
w_foo = space.appexec([], """():
class Foo(object):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit