Author: Armin Rigo <ar...@tunes.org>
Branch: 
Changeset: r44417:3bdfa021b9cb
Date: 2011-05-25 11:12 +0200
http://bitbucket.org/pypy/pypy/changeset/3bdfa021b9cb/

Log:    merge heads

diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py
--- a/pypy/objspace/descroperation.py
+++ b/pypy/objspace/descroperation.py
@@ -207,34 +207,48 @@
         return space.get_and_call_function(w_descr, w_obj, w_name)
 
     def is_true(space, w_obj):
-        w_descr = space.lookup(w_obj, '__nonzero__')
+        method = "__nonzero__"
+        w_descr = space.lookup(w_obj, method)
         if w_descr is None:
-            w_descr = space.lookup(w_obj, '__len__')
+            method = "__len__"
+            w_descr = space.lookup(w_obj, method)
             if w_descr is None:
                 return True
         w_res = space.get_and_call_function(w_descr, w_obj)
         # more shortcuts for common cases
-        if w_res is space.w_False:
+        if space.is_w(w_res, space.w_False):
             return False
-        if w_res is space.w_True:
+        if space.is_w(w_res, space.w_True):
             return True
         w_restype = space.type(w_res)
-        if (space.is_w(w_restype, space.w_bool) or
-            space.is_w(w_restype, space.w_int)):
+        # 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
         else:
-            raise OperationError(space.w_TypeError,
-                                 space.wrap('__nonzero__ should return '
-                                            'bool or int'))
+            msg = "%s should return bool or integer" % (method,)
+            raise OperationError(space.w_TypeError, space.wrap(msg))
 
-    def nonzero(self, w_obj):
-        if self.is_true(w_obj):
-            return self.w_True
+    def nonzero(space, w_obj):
+        if space.is_true(w_obj):
+            return space.w_True
         else:
-            return self.w_False
+            return space.w_False
 
-##    def len(self, w_obj):
-##        XXX needs to check that the result is an int (or long?) >= 0
+    def len(space, w_obj):
+        w_descr = space.lookup(w_obj, '__len__')
+        if w_descr is None:
+            name = space.type(w_obj).getname(space)
+            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
+
+    def _check_len_result(space, w_obj):
+        # Will complain if result is too big.
+        space.int_w(w_obj)
 
     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,6 +448,10 @@
     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
@@ -524,6 +524,20 @@
         assert issubclass(B, B)
         assert issubclass(23, B)
 
+    def test_truth_of_long(self):
+        class X(object):
+            def __len__(self): return 1L
+            __nonzero__ = __len__
+        assert X()
+        del X.__nonzero__
+        assert X()
+
+    def test_len_overflow(self):
+        import sys
+        class X(object):
+            def __len__(self):
+                return sys.maxsize + 1
+        raises(OverflowError, len, X())
 
 class AppTestWithBuiltinShortcut(AppTest_Descroperation):
     OPTIONS = {'objspace.std.builtinshortcut': True}
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to