- 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
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 @@
 
     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 @@
 ]
 
 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 @@
         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 @@
     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 @@
     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 @@
     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 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 @@
 
     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 @@
     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 @@
 
             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 @@
         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):