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

Reply via email to