[pypy-commit] pypy length-hint: fix mishandling of bad length hints in zip, add some related asserts

pjenvey noreply at buildbot.pypy.org
Sun Oct 7 20:41:55 CEST 2012


Author: Philip Jenvey <pjenvey at underboss.org>
Branch: length-hint
Changeset: r57858:c40b559e03ca
Date: 2012-10-05 11:28 -0700
http://bitbucket.org/pypy/pypy/changeset/c40b559e03ca/

Log:	fix mishandling of bad length hints in zip, add some related asserts

diff --git a/pypy/module/__builtin__/app_functional.py b/pypy/module/__builtin__/app_functional.py
--- a/pypy/module/__builtin__/app_functional.py
+++ b/pypy/module/__builtin__/app_functional.py
@@ -222,6 +222,8 @@
         hint = operator._length_hint(seq, min_hint)
         if min_hint == -1 or hint < min_hint:
             min_hint = hint
+    if min_hint == -1:
+        min_hint = 0
 
     with _ManagedNewlistHint(min_hint) as result:
         while True:
diff --git a/pypy/module/__builtin__/test/test_functional.py b/pypy/module/__builtin__/test/test_functional.py
--- a/pypy/module/__builtin__/test/test_functional.py
+++ b/pypy/module/__builtin__/test/test_functional.py
@@ -87,6 +87,15 @@
    def test_three_lists(self):
       assert zip([1,2,3], [1,2], [1,2,3]) == [(1,1,1), (2,2,2)]
 
+   def test_bad_length_hint(self):
+      class Foo(object):
+         def __length_hint__(self):
+            return NotImplemented
+         def __iter__(self):
+            if False:
+               yield None
+      assert zip(Foo()) == []
+
 class AppTestReduce:
    def test_None(self):
        raises(TypeError, reduce, lambda x, y: x+y, [1,2,3], None)
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
@@ -449,6 +449,7 @@
         pass
 
     def _resize_hint(self, w_list, hint):
+        assert hint >= 0
         if hint:
             w_list.strategy = SizeListStrategy(self.space, hint)
 
@@ -536,6 +537,7 @@
         ListStrategy.__init__(self, space)
 
     def _resize_hint(self, w_list, hint):
+        assert hint >= 0
         self.sizehint = hint
 
 class RangeListStrategy(ListStrategy):
@@ -572,7 +574,7 @@
 
     def _resize_hint(self, w_list, hint):
         # XXX: this could be supported
-        pass
+        assert hint >= 0
 
     def copy_into(self, w_list, w_other):
         w_other.strategy = self
diff --git a/pypy/rpython/lltypesystem/rlist.py b/pypy/rpython/lltypesystem/rlist.py
--- a/pypy/rpython/lltypesystem/rlist.py
+++ b/pypy/rpython/lltypesystem/rlist.py
@@ -222,6 +222,7 @@
     list to the newsize (and after the operation incase the initial
     guess lied).
     """
+    assert newsize >= 0, "negative list length"
     allocated = len(l.items)
     if allocated < newsize or newsize < (allocated >> 1) - 5:
         _ll_list_resize_hint_really(l, newsize, False)


More information about the pypy-commit mailing list