diff --git a/Demo/classes/Complex.py b/Demo/classes/Complex.py index a77989750f9..2019cdf32d9 100755 --- a/Demo/classes/Complex.py +++ b/Demo/classes/Complex.py @@ -165,7 +165,7 @@ class Complex: other = ToComplex(other) return cmp(other, self) - def __nonzero__(self): + def __bool__(self): return not (self.re == self.im == 0) abs = radius = __abs__ diff --git a/Demo/classes/Rat.py b/Demo/classes/Rat.py index 55543b6d2d2..24670b616b3 100755 --- a/Demo/classes/Rat.py +++ b/Demo/classes/Rat.py @@ -223,7 +223,7 @@ class Rat: return cmp(Rat(a), b) # a != 0 - def __nonzero__(a): + def __bool__(a): return a.__num != 0 # coercion diff --git a/Doc/lib/liboperator.tex b/Doc/lib/liboperator.tex index 5ba3209be01..867c2ab4c29 100644 --- a/Doc/lib/liboperator.tex +++ b/Doc/lib/liboperator.tex @@ -55,7 +55,7 @@ and support truth tests, identity tests, and boolean operations: Return the outcome of \keyword{not} \var{o}. (Note that there is no \method{__not__()} method for object instances; only the interpreter core defines this operation. The result is affected by the -\method{__nonzero__()} and \method{__len__()} methods.) +\method{__bool__()} and \method{__len__()} methods.) \end{funcdesc} \begin{funcdesc}{truth}{o} diff --git a/Doc/lib/libstdtypes.tex b/Doc/lib/libstdtypes.tex index d5409e03277..17e377beb86 100644 --- a/Doc/lib/libstdtypes.tex +++ b/Doc/lib/libstdtypes.tex @@ -51,7 +51,7 @@ The following values are considered false: \item any empty mapping, for example, \code{\{\}}. \item instances of user-defined classes, if the class defines a - \method{__nonzero__()} or \method{__len__()} method, when that + \method{__bool__()} or \method{__len__()} method, when that method returns the integer zero or \class{bool} value \code{False}.\footnote{Additional information on these special methods may be found in the diff --git a/Doc/lib/libtimeit.tex b/Doc/lib/libtimeit.tex index 1c4e05bafd4..2629439d8cc 100644 --- a/Doc/lib/libtimeit.tex +++ b/Doc/lib/libtimeit.tex @@ -162,13 +162,13 @@ the module interface) that compare the cost of using missing and present object attributes. \begin{verbatim} -% timeit.py 'try:' ' str.__nonzero__' 'except AttributeError:' ' pass' +% timeit.py 'try:' ' str.__bool__' 'except AttributeError:' ' pass' 100000 loops, best of 3: 15.7 usec per loop -% timeit.py 'if hasattr(str, "__nonzero__"): pass' +% timeit.py 'if hasattr(str, "__bool__"): pass' 100000 loops, best of 3: 4.26 usec per loop -% timeit.py 'try:' ' int.__nonzero__' 'except AttributeError:' ' pass' +% timeit.py 'try:' ' int.__bool__' 'except AttributeError:' ' pass' 1000000 loops, best of 3: 1.43 usec per loop -% timeit.py 'if hasattr(int, "__nonzero__"): pass' +% timeit.py 'if hasattr(int, "__bool__"): pass' 100000 loops, best of 3: 2.23 usec per loop \end{verbatim} @@ -176,7 +176,7 @@ missing and present object attributes. >>> import timeit >>> s = """\ ... try: -... str.__nonzero__ +... str.__bool__ ... except AttributeError: ... pass ... """ @@ -184,14 +184,14 @@ missing and present object attributes. >>> print "%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000) 17.09 usec/pass >>> s = """\ -... if hasattr(str, '__nonzero__'): pass +... if hasattr(str, '__bool__'): pass ... """ >>> t = timeit.Timer(stmt=s) >>> print "%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000) 4.85 usec/pass >>> s = """\ ... try: -... int.__nonzero__ +... int.__bool__ ... except AttributeError: ... pass ... """ @@ -199,7 +199,7 @@ missing and present object attributes. >>> print "%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000) 1.97 usec/pass >>> s = """\ -... if hasattr(int, '__nonzero__'): pass +... if hasattr(int, '__bool__'): pass ... """ >>> t = timeit.Timer(stmt=s) >>> print "%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000) diff --git a/Doc/lib/libwinreg.tex b/Doc/lib/libwinreg.tex index d1e23da51cb..38539977845 100644 --- a/Doc/lib/libwinreg.tex +++ b/Doc/lib/libwinreg.tex @@ -375,7 +375,7 @@ This module offers the following functions: also accept an integer, however, use of the handle object is encouraged. - Handle objects provide semantics for \method{__nonzero__()} - thus + Handle objects provide semantics for \method{__bool__()} - thus \begin{verbatim} if handle: print "Yes" diff --git a/Doc/lib/libxmlrpclib.tex b/Doc/lib/libxmlrpclib.tex index 3645b824d86..b08920ccb13 100644 --- a/Doc/lib/libxmlrpclib.tex +++ b/Doc/lib/libxmlrpclib.tex @@ -171,7 +171,7 @@ Hacks}{http://xmlrpc-c.sourceforge.net/hacks.php} page. This class may be initialized from any Python value; the instance returned depends only on its truth value. It supports various Python operators through \method{__cmp__()}, \method{__repr__()}, -\method{__int__()}, and \method{__nonzero__()} methods, all +\method{__int__()}, and \method{__bool__()} methods, all implemented in the obvious ways. It also has the following method, supported mainly for internal use by diff --git a/Doc/ref/ref3.tex b/Doc/ref/ref3.tex index 83277f44f58..7eddfcd6dc6 100644 --- a/Doc/ref/ref3.tex +++ b/Doc/ref/ref3.tex @@ -1313,13 +1313,13 @@ of that object]{2.5} \withsubitem{(object method)}{\ttindex{__cmp__()}} \end{methoddesc} -\begin{methoddesc}[object]{__nonzero__}{self} +\begin{methoddesc}[object]{__bool__}{self} Called to implement truth value testing, and the built-in operation -\code{bool()}; should return \code{False} or \code{True}, or their -integer equivalents \code{0} or \code{1}. +\code{bool()}; should return \code{False} or \code{True}. When this method is not defined, \method{__len__()} is -called, if it is defined (see below). If a class defines neither -\method{__len__()} nor \method{__nonzero__()}, all its instances are +called, if it is defined (see below) and \code{True} is returned when +the length is not zero. If a class defines neither +\method{__len__()} nor \method{__bool__()}, all its instances are considered true. \withsubitem{(mapping object method)}{\ttindex{__len__()}} \end{methoddesc} @@ -1693,9 +1693,9 @@ through the values. Called to implement the built-in function \function{len()}\bifuncindex{len}. Should return the length of the object, an integer \code{>=} 0. Also, an object that doesn't define a -\method{__nonzero__()} method and whose \method{__len__()} method +\method{__bool__()} method and whose \method{__len__()} method returns zero is considered to be false in a Boolean context. -\withsubitem{(object method)}{\ttindex{__nonzero__()}} +\withsubitem{(object method)}{\ttindex{__bool__()}} \end{methoddesc} \begin{methoddesc}[container object]{__getitem__}{self, key} diff --git a/Include/object.h b/Include/object.h index 80447a91fab..83a2c54b58c 100644 --- a/Include/object.h +++ b/Include/object.h @@ -160,7 +160,7 @@ typedef struct { unaryfunc nb_negative; unaryfunc nb_positive; unaryfunc nb_absolute; - inquiry nb_nonzero; + inquiry nb_bool; unaryfunc nb_invert; binaryfunc nb_lshift; binaryfunc nb_rshift; diff --git a/Lib/decimal.py b/Lib/decimal.py index 99c0de6d328..4557e6a8f1a 100644 --- a/Lib/decimal.py +++ b/Lib/decimal.py @@ -633,14 +633,14 @@ class Decimal(object): return other return 0 - def __nonzero__(self): + def __bool__(self): """Is the number non-zero? 0 if self == 0 1 if self != 0 """ if self._is_special: - return 1 + return True return sum(self._int) != 0 def __cmp__(self, other, context=None): @@ -759,7 +759,7 @@ class Decimal(object): i = int(self) if self == Decimal(i): return hash(i) - assert self.__nonzero__() # '-0' handled by integer case + assert self.__bool__() # '-0' handled by integer case return hash(str(self.normalize())) def as_tuple(self): diff --git a/Lib/test/test_bool.py b/Lib/test/test_bool.py index 97ac4809a5c..8121e03e067 100644 --- a/Lib/test/test_bool.py +++ b/Lib/test/test_bool.py @@ -335,24 +335,51 @@ class BoolTest(unittest.TestCase): def test_convert_to_bool(self): # Verify that TypeError occurs when bad things are returned - # from __nonzero__(). This isn't really a bool test, but + # from __bool__(). This isn't really a bool test, but # it's related. check = lambda o: self.assertRaises(TypeError, bool, o) class Foo(object): - def __nonzero__(self): + def __bool__(self): return self check(Foo()) class Bar(object): - def __nonzero__(self): + def __bool__(self): return "Yes" check(Bar()) class Baz(int): - def __nonzero__(self): + def __bool__(self): return self check(Baz()) + # __bool__() must return a bool not an int + class Spam(int): + def __bool__(self): + return 1 + check(Spam()) + + class Eggs: + def __len__(self): + return -1 + self.assertRaises(ValueError, bool, Eggs()) + + 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), e_bool: + pass + try: + len(A()) + except (Exception), e_len: + pass + self.assertEqual(str(e_bool), str(e_len)) def test_main(): test_support.run_unittest(BoolTest) diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 272af863621..7b245d17d30 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -94,7 +94,7 @@ if have_unicode: ] class TestFailingBool: - def __nonzero__(self): + def __bool__(self): raise RuntimeError class TestFailingIter: diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index 5fef4eb5cce..55a53d30f7b 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -990,7 +990,7 @@ class DecimalUsabilityTest(unittest.TestCase): checkSameDec("__mod__", True) checkSameDec("__mul__", True) checkSameDec("__neg__") - checkSameDec("__nonzero__") + checkSameDec("__bool__") checkSameDec("__pos__") checkSameDec("__pow__", True) checkSameDec("__radd__", True) diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index b2e7e665cc3..d3ae4551ab8 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -417,8 +417,8 @@ def ints(): if verbose: print "Testing int operations..." numops(100, 3) # The following crashes in Python 2.2 - vereq((1).__nonzero__(), 1) - vereq((0).__nonzero__(), 0) + vereq((1).__bool__(), True) + vereq((0).__bool__(), False) # This returns 'NotImplemented' in Python 2.2 class C(int): def __add__(self, other): @@ -1682,7 +1682,7 @@ def specials(): class Proxy(object): def __init__(self, x): self.x = x - def __nonzero__(self): + def __bool__(self): return not not self.x def __hash__(self): return hash(self.x) @@ -1722,7 +1722,7 @@ def specials(): class DProxy(object): def __init__(self, x): self.x = x - def __nonzero__(self): + def __bool__(self): return not not self.x def __hash__(self): return hash(self.x) diff --git a/Lib/test/test_iter.py b/Lib/test/test_iter.py index 0ac34c8220e..76af429de10 100644 --- a/Lib/test/test_iter.py +++ b/Lib/test/test_iter.py @@ -327,10 +327,10 @@ class TestCase(unittest.TestCase): class Boolean: def __init__(self, truth): self.truth = truth - def __nonzero__(self): + def __bool__(self): return self.truth - bTrue = Boolean(1) - bFalse = Boolean(0) + bTrue = Boolean(True) + bFalse = Boolean(False) class Seq: def __init__(self, *args): diff --git a/Lib/test/test_operator.py b/Lib/test/test_operator.py index 50c3b0c12ca..152d5ecb895 100644 --- a/Lib/test/test_operator.py +++ b/Lib/test/test_operator.py @@ -319,7 +319,7 @@ class OperatorTestCase(unittest.TestCase): def test_truth(self): class C(object): - def __nonzero__(self): + def __bool__(self): raise SyntaxError self.failUnlessRaises(TypeError, operator.truth) self.failUnlessRaises(SyntaxError, operator.truth, C()) diff --git a/Lib/test/test_richcmp.py b/Lib/test/test_richcmp.py index f412a89055c..9c4a7a05e61 100644 --- a/Lib/test/test_richcmp.py +++ b/Lib/test/test_richcmp.py @@ -51,7 +51,7 @@ class Vector: def __hash__(self): raise TypeError, "Vectors cannot be hashed" - def __nonzero__(self): + def __bool__(self): raise TypeError, "Vectors cannot be used in Boolean contexts" def __cmp__(self, other): @@ -133,7 +133,7 @@ class VectorTest(unittest.TestCase): for ops in opmap.itervalues(): for op in ops: - # calls __nonzero__, which should fail + # calls __bool__, which should fail self.assertRaises(TypeError, bool, op(a, b)) class NumberTest(unittest.TestCase): @@ -208,13 +208,13 @@ class MiscTest(unittest.TestCase): self.assertRaises(RuntimeError, cmp, a, b) def test_not(self): - # Check that exceptions in __nonzero__ are properly + # Check that exceptions in __bool__ are properly # propagated by the not operator import operator class Exc(Exception): pass class Bad: - def __nonzero__(self): + def __bool__(self): raise Exc def do(bad): diff --git a/Lib/xml/dom/minidom.py b/Lib/xml/dom/minidom.py index 028e809ca32..bfdcc82c025 100644 --- a/Lib/xml/dom/minidom.py +++ b/Lib/xml/dom/minidom.py @@ -38,7 +38,7 @@ class Node(xml.dom.Node): prefix = EMPTY_PREFIX # non-null only for NS elements and attributes - def __nonzero__(self): + def __bool__(self): return True def toxml(self, encoding = None): diff --git a/Misc/NEWS b/Misc/NEWS index 3f57fcbfeb1..2c37fc20dac 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -36,6 +36,8 @@ TO DO Core and Builtins ----------------- +- Renamed nb_nonzero to nb_bool and __nonzero__ to __bool__ + - Classic classes are a thing of the past. All classes are new style. - Exceptions *must* derive from BaseException. diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index e4aae2d10fc..7948516401b 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -4017,7 +4017,7 @@ static PyMethodDef Simple_methods[] = { { NULL, NULL }, }; -static int Simple_nonzero(CDataObject *self) +static int Simple_bool(CDataObject *self) { return memcmp(self->b_ptr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", self->b_size); } @@ -4032,7 +4032,7 @@ static PyNumberMethods Simple_as_number = { 0, /* nb_negative */ 0, /* nb_positive */ 0, /* nb_absolute */ - (inquiry)Simple_nonzero, /* nb_nonzero */ + (inquiry)Simple_bool, /* nb_bool */ }; #if (PY_VERSION_HEX < 0x02040000) @@ -4364,7 +4364,7 @@ static PySequenceMethods Pointer_as_sequence = { }; static int -Pointer_nonzero(CDataObject *self) +Pointer_bool(CDataObject *self) { return *(void **)self->b_ptr != NULL; } @@ -4379,7 +4379,7 @@ static PyNumberMethods Pointer_as_number = { 0, /* nb_negative */ 0, /* nb_positive */ 0, /* nb_absolute */ - (inquiry)Pointer_nonzero, /* nb_nonzero */ + (inquiry)Pointer_bool, /* nb_bool */ }; PyTypeObject Pointer_Type = { diff --git a/Modules/datetimemodule.c b/Modules/datetimemodule.c index 4c05134f4f1..b57ccbcb009 100644 --- a/Modules/datetimemodule.c +++ b/Modules/datetimemodule.c @@ -1958,7 +1958,7 @@ Done: } static int -delta_nonzero(PyDateTime_Delta *self) +delta_bool(PyDateTime_Delta *self) { return (GET_TD_DAYS(self) != 0 || GET_TD_SECONDS(self) != 0 @@ -2083,7 +2083,7 @@ static PyNumberMethods delta_as_number = { (unaryfunc)delta_negative, /* nb_negative */ (unaryfunc)delta_positive, /* nb_positive */ (unaryfunc)delta_abs, /* nb_absolute */ - (inquiry)delta_nonzero, /* nb_nonzero */ + (inquiry)delta_bool, /* nb_bool */ 0, /*nb_invert*/ 0, /*nb_lshift*/ 0, /*nb_rshift*/ @@ -2653,7 +2653,7 @@ static PyNumberMethods date_as_number = { 0, /* nb_negative */ 0, /* nb_positive */ 0, /* nb_absolute */ - 0, /* nb_nonzero */ + 0, /* nb_bool */ }; static PyTypeObject PyDateTime_DateType = { @@ -3324,7 +3324,7 @@ time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw) } static int -time_nonzero(PyDateTime_Time *self) +time_bool(PyDateTime_Time *self) { int offset; int none; @@ -3418,7 +3418,7 @@ static PyNumberMethods time_as_number = { 0, /* nb_negative */ 0, /* nb_positive */ 0, /* nb_absolute */ - (inquiry)time_nonzero, /* nb_nonzero */ + (inquiry)time_bool, /* nb_bool */ }; static PyTypeObject PyDateTime_TimeType = { @@ -4501,7 +4501,7 @@ static PyNumberMethods datetime_as_number = { 0, /* nb_negative */ 0, /* nb_positive */ 0, /* nb_absolute */ - 0, /* nb_nonzero */ + 0, /* nb_bool */ }; static PyTypeObject PyDateTime_DateTimeType = { diff --git a/Objects/boolobject.c b/Objects/boolobject.c index a0d6cd53ec7..cd194819373 100644 --- a/Objects/boolobject.c +++ b/Objects/boolobject.c @@ -112,7 +112,7 @@ static PyNumberMethods bool_as_number = { 0, /* nb_negative */ 0, /* nb_positive */ 0, /* nb_absolute */ - 0, /* nb_nonzero */ + 0, /* nb_bool */ 0, /* nb_invert */ 0, /* nb_lshift */ 0, /* nb_rshift */ diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 2713e3eeec1..da47f8116bf 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -568,7 +568,7 @@ complex_abs(PyComplexObject *v) } static int -complex_nonzero(PyComplexObject *v) +complex_bool(PyComplexObject *v) { return v->cval.real != 0.0 || v->cval.imag != 0.0; } @@ -938,7 +938,7 @@ static PyNumberMethods complex_as_number = { (unaryfunc)complex_neg, /* nb_negative */ (unaryfunc)complex_pos, /* nb_positive */ (unaryfunc)complex_abs, /* nb_absolute */ - (inquiry)complex_nonzero, /* nb_nonzero */ + (inquiry)complex_bool, /* nb_bool */ 0, /* nb_invert */ 0, /* nb_lshift */ 0, /* nb_rshift */ diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 40126b2a6b4..aab76122749 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -837,7 +837,7 @@ float_abs(PyFloatObject *v) } static int -float_nonzero(PyFloatObject *v) +float_bool(PyFloatObject *v) { return v->ob_fval != 0.0; } @@ -1087,7 +1087,7 @@ static PyNumberMethods float_as_number = { (unaryfunc)float_neg, /*nb_negative*/ (unaryfunc)float_pos, /*nb_positive*/ (unaryfunc)float_abs, /*nb_absolute*/ - (inquiry)float_nonzero, /*nb_nonzero*/ + (inquiry)float_bool, /*nb_bool*/ 0, /*nb_invert*/ 0, /*nb_lshift*/ 0, /*nb_rshift*/ diff --git a/Objects/intobject.c b/Objects/intobject.c index e64d0b1f9a0..b420c128bde 100644 --- a/Objects/intobject.c +++ b/Objects/intobject.c @@ -780,7 +780,7 @@ int_abs(PyIntObject *v) } static int -int_nonzero(PyIntObject *v) +int_bool(PyIntObject *v) { return v->ob_ival != 0; } @@ -1034,14 +1034,14 @@ static PyNumberMethods int_as_number = { (unaryfunc)int_neg, /*nb_negative*/ (unaryfunc)int_pos, /*nb_positive*/ (unaryfunc)int_abs, /*nb_absolute*/ - (inquiry)int_nonzero, /*nb_nonzero*/ + (inquiry)int_bool, /*nb_bool*/ (unaryfunc)int_invert, /*nb_invert*/ (binaryfunc)int_lshift, /*nb_lshift*/ (binaryfunc)int_rshift, /*nb_rshift*/ (binaryfunc)int_and, /*nb_and*/ (binaryfunc)int_xor, /*nb_xor*/ (binaryfunc)int_or, /*nb_or*/ - 0, /*nb_coerce*/ + 0, /*nb_coerce*/ (unaryfunc)int_int, /*nb_int*/ (unaryfunc)int_long, /*nb_long*/ (unaryfunc)int_float, /*nb_float*/ diff --git a/Objects/longobject.c b/Objects/longobject.c index 87082cbb014..566e6a7547c 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -2886,7 +2886,7 @@ long_abs(PyLongObject *v) } static int -long_nonzero(PyLongObject *v) +long_bool(PyLongObject *v) { return ABS(v->ob_size) != 0; } @@ -3307,7 +3307,7 @@ static PyNumberMethods long_as_number = { (unaryfunc) long_neg, /*nb_negative*/ (unaryfunc) long_pos, /*tp_positive*/ (unaryfunc) long_abs, /*tp_absolute*/ - (inquiry) long_nonzero, /*tp_nonzero*/ + (inquiry) long_bool, /*tp_bool*/ (unaryfunc) long_invert, /*nb_invert*/ long_lshift, /*nb_lshift*/ (binaryfunc) long_rshift, /*nb_rshift*/ diff --git a/Objects/object.c b/Objects/object.c index e202e9ba0fb..4d9f414ffc8 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1246,8 +1246,8 @@ PyObject_IsTrue(PyObject *v) if (v == Py_None) return 0; else if (v->ob_type->tp_as_number != NULL && - v->ob_type->tp_as_number->nb_nonzero != NULL) - res = (*v->ob_type->tp_as_number->nb_nonzero)(v); + v->ob_type->tp_as_number->nb_bool != NULL) + res = (*v->ob_type->tp_as_number->nb_bool)(v); else if (v->ob_type->tp_as_mapping != NULL && v->ob_type->tp_as_mapping->mp_length != NULL) res = (*v->ob_type->tp_as_mapping->mp_length)(v); diff --git a/Objects/setobject.c b/Objects/setobject.c index 05549e6cfff..d489711270d 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -1784,7 +1784,7 @@ static PyNumberMethods set_as_number = { 0, /*nb_negative*/ 0, /*nb_positive*/ 0, /*nb_absolute*/ - 0, /*nb_nonzero*/ + 0, /*nb_bool*/ 0, /*nb_invert*/ 0, /*nb_lshift*/ 0, /*nb_rshift*/ @@ -1894,7 +1894,7 @@ static PyNumberMethods frozenset_as_number = { 0, /*nb_negative*/ 0, /*nb_positive*/ 0, /*nb_absolute*/ - 0, /*nb_nonzero*/ + 0, /*nb_bool*/ 0, /*nb_invert*/ 0, /*nb_lshift*/ 0, /*nb_rshift*/ diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 074fad9b2c5..ea1d1a28db9 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2928,7 +2928,7 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) COPYNUM(nb_negative); COPYNUM(nb_positive); COPYNUM(nb_absolute); - COPYNUM(nb_nonzero); + COPYNUM(nb_bool); COPYNUM(nb_invert); COPYNUM(nb_lshift); COPYNUM(nb_rshift); @@ -4206,32 +4206,39 @@ SLOT0(slot_nb_positive, "__pos__") SLOT0(slot_nb_absolute, "__abs__") static int -slot_nb_nonzero(PyObject *self) +slot_nb_bool(PyObject *self) { PyObject *func, *args; - static PyObject *nonzero_str, *len_str; + static PyObject *bool_str, *len_str; int result = -1; + int from_len = 0; - func = lookup_maybe(self, "__nonzero__", &nonzero_str); + func = lookup_maybe(self, "__bool__", &bool_str); if (func == NULL) { if (PyErr_Occurred()) return -1; func = lookup_maybe(self, "__len__", &len_str); if (func == NULL) return PyErr_Occurred() ? -1 : 1; + from_len = 1; } args = PyTuple_New(0); if (args != NULL) { PyObject *temp = PyObject_Call(func, args, NULL); Py_DECREF(args); if (temp != NULL) { - if (PyInt_CheckExact(temp) || PyBool_Check(temp)) + if (from_len) { + /* enforced by slot_nb_len */ result = PyObject_IsTrue(temp); + } + else if (PyBool_Check(temp)) { + result = PyObject_IsTrue(temp); + } else { PyErr_Format(PyExc_TypeError, - "__nonzero__ should return " - "bool or int, returned %s", - temp->ob_type->tp_name); + "__bool__ should return " + "bool, returned %s", + temp->ob_type->tp_name); result = -1; } Py_DECREF(temp); @@ -4887,7 +4894,7 @@ static slotdef slotdefs[] = { UNSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc, "+x"), UNSLOT("__abs__", nb_absolute, slot_nb_absolute, wrap_unaryfunc, "abs(x)"), - UNSLOT("__nonzero__", nb_nonzero, slot_nb_nonzero, wrap_inquirypred, + UNSLOT("__bool__", nb_bool, slot_nb_bool, wrap_inquirypred, "x != 0"), UNSLOT("__invert__", nb_invert, slot_nb_invert, wrap_unaryfunc, "~x"), BINSLOT("__lshift__", nb_lshift, slot_nb_lshift, "<<"), diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index 206a45512b6..e05788fc404 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -499,7 +499,7 @@ WRAP_BINARY(proxy_ixor, PyNumber_InPlaceXor) WRAP_BINARY(proxy_ior, PyNumber_InPlaceOr) static int -proxy_nonzero(PyWeakReference *proxy) +proxy_bool(PyWeakReference *proxy) { PyObject *o = PyWeakref_GET_OBJECT(proxy); if (!proxy_checkref(proxy)) @@ -596,7 +596,7 @@ static PyNumberMethods proxy_as_number = { proxy_neg, /*nb_negative*/ proxy_pos, /*nb_positive*/ proxy_abs, /*nb_absolute*/ - (inquiry)proxy_nonzero, /*nb_nonzero*/ + (inquiry)proxy_bool, /*nb_bool*/ proxy_invert, /*nb_invert*/ proxy_lshift, /*nb_lshift*/ proxy_rshift, /*nb_rshift*/ diff --git a/PC/_winreg.c b/PC/_winreg.c index c50103332b2..bacb9ddb0ab 100644 --- a/PC/_winreg.c +++ b/PC/_winreg.c @@ -305,7 +305,7 @@ PyDoc_STRVAR(PyHKEY_doc, "handle - The integer Win32 handle.\n" "\n" "Operations:\n" -"__nonzero__ - Handles with an open object return true, otherwise false.\n" +"__bool__ - Handles with an open object return true, otherwise false.\n" "__int__ - Converting a handle to an integer returns the Win32 handle.\n" "__cmp__ - Handle objects are compared using the handle value."); @@ -375,7 +375,7 @@ PyHKEY_deallocFunc(PyObject *ob) } static int -PyHKEY_nonzeroFunc(PyObject *ob) +PyHKEY_boolFunc(PyObject *ob) { return ((PyHKEYObject *)ob)->hkey != 0; } @@ -437,7 +437,7 @@ static PyNumberMethods PyHKEY_NumberMethods = PyHKEY_unaryFailureFunc, /* nb_negative */ PyHKEY_unaryFailureFunc, /* nb_positive */ PyHKEY_unaryFailureFunc, /* nb_absolute */ - PyHKEY_nonzeroFunc, /* nb_nonzero */ + PyHKEY_boolFunc, /* nb_bool */ PyHKEY_unaryFailureFunc, /* nb_invert */ PyHKEY_binaryFailureFunc, /* nb_lshift */ PyHKEY_binaryFailureFunc, /* nb_rshift */