[pypy-commit] pypy default: fix returning an object which defines an __int__ from an __len__ method.

alex_gaynor noreply at buildbot.pypy.org
Sun Oct 2 00:42:28 CEST 2011


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: 
Changeset: r47757:6e2b325c768e
Date: 2011-10-01 18:42 -0400
http://bitbucket.org/pypy/pypy/changeset/6e2b325c768e/

Log:	fix returning an object which defines an __int__ from an __len__
	method.

diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py
--- a/pypy/objspace/descroperation.py
+++ b/pypy/objspace/descroperation.py
@@ -258,15 +258,15 @@
             msg = "'%s' has no length" % (name,)
             raise OperationError(space.w_TypeError, space.wrap(msg))
         w_res = space.get_and_call_function(w_descr, w_obj)
-        space._check_len_result(w_res)
-        return w_res
+        return space.wrap(space._check_len_result(w_res))
 
     def _check_len_result(space, w_obj):
         # Will complain if result is too big.
-        result = space.int_w(w_obj)
+        result = space.int_w(space.int(w_obj))
         if result < 0:
             raise OperationError(space.w_ValueError,
                                  space.wrap("__len__() should return >= 0"))
+        return result
 
     def iter(space, w_obj):
         w_descr = space.lookup(w_obj, '__iter__')
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
@@ -667,5 +667,19 @@
                 return -1L
         raises(ValueError, len, Y())
 
+    def test_len_custom__int__(self):
+        class X(object):
+            def __init__(self, x):
+                self.x = x
+            def __len__(self):
+                return self.x
+            def __int__(self):
+                return self.x
+
+        l = len(X(3.0))
+        assert l == 3 and type(l) is int
+        l = len(X(X(2)))
+        assert l == 2 and type(l) is int
+
 class AppTestWithBuiltinShortcut(AppTest_Descroperation):
     OPTIONS = {'objspace.std.builtinshortcut': True}


More information about the pypy-commit mailing list