[pypy-commit] pypy py3k: Use the same check (and error message) for bool() and len(),

amauryfa noreply at buildbot.pypy.org
Sun Dec 18 19:34:28 CET 2011


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: py3k
Changeset: r50670:4508c3d16324
Date: 2011-12-18 17:43 +0100
http://bitbucket.org/pypy/pypy/changeset/4508c3d16324/

Log:	Use the same check (and error message) for bool() and len(), when
	the same __len__ method is used for both.

diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py
--- a/pypy/objspace/descroperation.py
+++ b/pypy/objspace/descroperation.py
@@ -236,14 +236,11 @@
         if space.is_w(w_res, space.w_True):
             return True
         w_restype = space.type(w_res)
-        # Note there is no check for bool here because the only possible
-        # instances of bool are w_False and w_True, which are checked above.
-        if (space.is_w(w_restype, space.w_int) or
-            space.is_w(w_restype, space.w_long)):
-            return space.int_w(w_res) != 0
+        if method == '__len__':
+            return space._check_len_result(w_res) != 0
         else:
-            msg = "%s should return bool or integer" % (method,)
-            raise OperationError(space.w_TypeError, space.wrap(msg))
+            raise OperationError(space.w_TypeError, space.wrap(
+                    "__bool__ should return bool"))
 
     def nonzero(space, w_obj):
         if space.is_true(w_obj):
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
@@ -677,5 +677,20 @@
         l = len(X(X(2)))
         assert l == 2 and type(l) is int
 
+    def test_sane_len(self):
+        # this test just tests our assumptions about __len__
+        # this will start failing if __len__ changes assertions
+        for badval in ['illegal', -1, 1 << 32]:
+            class A:
+                def __len__(self):
+                    return badval
+            try:
+                bool(A())
+            except (Exception) as e_bool:
+                try:
+                    len(A())
+                except (Exception) as e_len:
+                    assert str(e_bool) == str(e_len)
+
 class AppTestWithBuiltinShortcut(AppTest_Descroperation):
     OPTIONS = {'objspace.std.builtinshortcut': True}


More information about the pypy-commit mailing list