Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r44418:c7eb8ff71d32
Date: 2011-05-25 11:19 +0200
http://bitbucket.org/pypy/pypy/changeset/c7eb8ff71d32/

Log:    Also check that __len__() doesn't return a negative answer. This
        kind of cancels the performance hack of _check_len_result(), which
        was quite minor anyway, so I think it can just go.

diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py
--- a/pypy/objspace/descroperation.py
+++ b/pypy/objspace/descroperation.py
@@ -248,7 +248,10 @@
 
     def _check_len_result(space, w_obj):
         # Will complain if result is too big.
-        space.int_w(w_obj)
+        result = space.int_w(w_obj)
+        if result < 0:
+            raise OperationError(space.w_ValueError,
+                                 space.wrap("__len__() should return >= 0"))
 
     def iter(space, w_obj):
         w_descr = space.lookup(w_obj, '__iter__')
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
@@ -448,10 +448,6 @@
     def is_w(self, w_one, w_two):
         return w_one is w_two
 
-    def _check_len_result(self, w_obj):
-        if type(w_obj) is not W_IntObject:
-            DescrOperation._check_len_result(self, w_obj)
-
     def is_true(self, w_obj):
         # a shortcut for performance
         # NOTE! this method is typically overridden by builtinshortcut.py.
diff --git a/pypy/objspace/test/test_descroperation.py 
b/pypy/objspace/test/test_descroperation.py
--- a/pypy/objspace/test/test_descroperation.py
+++ b/pypy/objspace/test/test_descroperation.py
@@ -539,5 +539,16 @@
                 return sys.maxsize + 1
         raises(OverflowError, len, X())
 
+    def test_len_underflow(self):
+        import sys
+        class X(object):
+            def __len__(self):
+                return -1
+        raises(ValueError, len, X())
+        class Y(object):
+            def __len__(self):
+                return -1L
+        raises(ValueError, len, Y())
+
 class AppTestWithBuiltinShortcut(AppTest_Descroperation):
     OPTIONS = {'objspace.std.builtinshortcut': True}
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to