Author: Armin Rigo <[email protected]>
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
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit