From 4dafcc4ece09c2a60473bb109513de4e7d2c2b11 Mon Sep 17 00:00:00 2001
From: Jack Diederich <jackdied@gmail.com>
Date: Tue, 28 Nov 2006 19:15:13 +0000
Subject: - patch #1600346 submitted by Tomer Filiba - Renamed nb_nonzero slots
 to nb_bool - Renamed __nonzero__ methods to __bool__ - update core, lib,
 docs, and tests to match

---
 Demo/classes/Complex.py   |  2 +-
 Demo/classes/Rat.py       |  2 +-
 Doc/lib/liboperator.tex   |  2 +-
 Doc/lib/libstdtypes.tex   |  2 +-
 Doc/lib/libtimeit.tex     | 16 ++++++++--------
 Doc/lib/libwinreg.tex     |  2 +-
 Doc/lib/libxmlrpclib.tex  |  2 +-
 Doc/ref/ref3.tex          | 14 +++++++-------
 Include/object.h          |  2 +-
 Lib/decimal.py            |  6 +++---
 Lib/test/test_bool.py     | 35 +++++++++++++++++++++++++++++++----
 Lib/test/test_builtin.py  |  2 +-
 Lib/test/test_decimal.py  |  2 +-
 Lib/test/test_descr.py    |  8 ++++----
 Lib/test/test_iter.py     |  6 +++---
 Lib/test/test_operator.py |  2 +-
 Lib/test/test_richcmp.py  |  8 ++++----
 Lib/xml/dom/minidom.py    |  2 +-
 Misc/NEWS                 |  2 ++
 Modules/_ctypes/_ctypes.c |  8 ++++----
 Modules/datetimemodule.c  | 12 ++++++------
 Objects/boolobject.c      |  2 +-
 Objects/complexobject.c   |  4 ++--
 Objects/floatobject.c     |  4 ++--
 Objects/intobject.c       |  6 +++---
 Objects/longobject.c      |  4 ++--
 Objects/object.c          |  4 ++--
 Objects/setobject.c       |  4 ++--
 Objects/typeobject.c      | 25 ++++++++++++++++---------
 Objects/weakrefobject.c   |  4 ++--
 PC/_winreg.c              |  6 +++---
 31 files changed, 118 insertions(+), 82 deletions(-)

diff --git a/Demo/classes/Complex.py b/Demo/classes/Complex.py
index a779897..2019cdf 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 55543b6..24670b6 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 5ba3209..867c2ab 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 d5409e0..17e377b 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 1c4e05b..2629439 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 d1e23da..3853997 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 3645b82..b08920c 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 83277f4..7eddfcd 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 80447a9..83a2c54 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 99c0de6..4557e6a 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 97ac480..8121e03 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 272af86..7b245d1 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 5fef4eb..55a53d3 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 b2e7e66..d3ae455 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 0ac34c8..76af429 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 50c3b0c..152d5ec 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 f412a89..9c4a7a0 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 028e809..bfdcc82 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 3f57fcb..2c37fc20 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 e4aae2d..7948516 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 4c05134..b57ccbc 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 a0d6cd5..cd19481 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 2713e3e..da47f81 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 40126b2..aab7612 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 e64d0b1..b420c12 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 87082cb..566e6a7 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 e202e9b..4d9f414 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 05549e6..d489711 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 074fad9..ea1d1a2 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 206a455..e05788f 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 c501033..bacb9dd 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 */
-- 
cgit v0.12

