From 8d901a7300bae8bb952910473787299517d52da5 Mon Sep 17 00:00:00 2001 From: "Jeong, YunWon" Date: Tue, 13 Jan 2026 18:42:52 +0900 Subject: [PATCH] Implement bool(NotImplemented) --- Lib/test/test_builtin.py | 21 +++++++++------------ crates/vm/src/builtins/singletons.rs | 9 +++++---- extra_tests/snippets/builtin_bool.py | 4 +++- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 38fd9ab95..cbba54a3b 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -2010,21 +2010,18 @@ class BuiltinTest(unittest.TestCase): self.assertRaises(TypeError, tp, 1, 2) self.assertRaises(TypeError, tp, a=1, b=2) - # TODO: RUSTPYTHON - @unittest.expectedFailure - def test_warning_notimplemented(self): - # Issue #35712: NotImplemented is a sentinel value that should never + def test_bool_notimplemented(self): + # GH-79893: NotImplemented is a sentinel value that should never # be evaluated in a boolean context (virtually all such use cases # are a result of accidental misuse implementing rich comparison # operations in terms of one another). - # For the time being, it will continue to evaluate as a true value, but - # issue a deprecation warning (with the eventual intent to make it - # a TypeError). - self.assertWarns(DeprecationWarning, bool, NotImplemented) - with self.assertWarns(DeprecationWarning): - self.assertTrue(NotImplemented) - with self.assertWarns(DeprecationWarning): - self.assertFalse(not NotImplemented) + msg = "NotImplemented should not be used in a boolean context" + self.assertRaisesRegex(TypeError, msg, bool, NotImplemented) + with self.assertRaisesRegex(TypeError, msg): + if NotImplemented: + pass + with self.assertRaisesRegex(TypeError, msg): + not NotImplemented class TestBreakpoint(unittest.TestCase): diff --git a/crates/vm/src/builtins/singletons.rs b/crates/vm/src/builtins/singletons.rs index 61ab1968a..169104efe 100644 --- a/crates/vm/src/builtins/singletons.rs +++ b/crates/vm/src/builtins/singletons.rs @@ -108,11 +108,12 @@ impl PyNotImplemented { impl AsNumber for PyNotImplemented { fn as_number() -> &'static PyNumberMethods { - // TODO: As per https://bugs.python.org/issue35712, using NotImplemented - // in boolean contexts will need to raise a DeprecationWarning in 3.9 - // and, eventually, a TypeError. static AS_NUMBER: PyNumberMethods = PyNumberMethods { - boolean: Some(|_number, _vm| Ok(true)), + boolean: Some(|_number, vm| { + Err(vm.new_type_error( + "NotImplemented should not be used in a boolean context".to_owned(), + )) + }), ..PyNumberMethods::NOT_IMPLEMENTED }; &AS_NUMBER diff --git a/extra_tests/snippets/builtin_bool.py b/extra_tests/snippets/builtin_bool.py index 6b6b4e0e0..902ed0cce 100644 --- a/extra_tests/snippets/builtin_bool.py +++ b/extra_tests/snippets/builtin_bool.py @@ -18,7 +18,9 @@ assert bool() is False assert bool(1) is True assert bool({}) is False -assert bool(NotImplemented) is True +# NotImplemented cannot be used in a boolean context (Python 3.14+) +with assert_raises(TypeError): + bool(NotImplemented) assert bool(...) is True if not 1: