gh-82012: Deprecate bitwise inversion (~) of bool (#103487)

The bitwise inversion operator on bool returns the bitwise inversion of the
underlying int value; i.e. `~True == -2` such that `bool(~True) == True`.

It's a common pitfall that users mistake `~` as negation operator and actually
want `not`. Supporting `~` is an artifact of bool inheriting from int. Since there
is no real use-case for the current behavior, let's deprecate `~` on bool and
later raise an error. This removes a potential source errors for users.

Full reasoning: https://github.com/python/cpython/issues/82012#issuecomment-1258705971

Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com>
This commit is contained in:
Tim Hoffmann 2023-05-03 09:00:42 +02:00 committed by GitHub
parent 5b05b013ff
commit fdb3ef8c0f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 78 additions and 25 deletions

View file

@ -58,8 +58,22 @@ class BoolTest(unittest.TestCase):
self.assertEqual(-True, -1)
self.assertEqual(abs(True), 1)
self.assertIsNot(abs(True), True)
self.assertEqual(~False, -1)
self.assertEqual(~True, -2)
with self.assertWarns(DeprecationWarning):
# We need to put the bool in a variable, because the constant
# ~False is evaluated at compile time due to constant folding;
# consequently the DeprecationWarning would be issued during
# module loading and not during test execution.
false = False
self.assertEqual(~false, -1)
with self.assertWarns(DeprecationWarning):
# also check that the warning is issued in case of constant
# folding at compile time
self.assertEqual(eval("~False"), -1)
with self.assertWarns(DeprecationWarning):
true = True
self.assertEqual(~true, -2)
with self.assertWarns(DeprecationWarning):
self.assertEqual(eval("~True"), -2)
self.assertEqual(False+2, 2)
self.assertEqual(True+2, 3)