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