Repository navigation
~bool deprecation not reported for literals #134280
Copy link
Copy link
Closed
Labels
3.13only security fixesonly security fixes3.14bugs and security fixesbugs and security fixes3.15bugs and security fixesbugs and security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Description
Bug report
Bug description:
Related to: #103487
# literal.py
print(~False)
print(~True)
# var.py
a = True
print(~a)
b = False
print(~b)A DeprecationWarning is reported for var.py, but not for literal.py.
$ python -c 'import sys; print(sys.version)'
3.15.0a0 (heads/main:42d03f3, May 19 2025, 23:32:01) [GCC 15.1.1 20250425 (Red Hat 15.1.1-1)]
$ python literal.py
-1
-2
$ python var.py
/tmp/scratch/var.py:2: DeprecationWarning: Bitwise inversion '~' on bool is deprecated and will be removed in Python 3.16. This returns the bitwise inversion of the underlying int object and is usually not what you expect from negating a bool. Use the 'not' operator for boolean negation or ~int(x) if you really want the bitwise inversion of the underlying int.
print(~a)
-2
/tmp/scratch/var.py:5: DeprecationWarning: Bitwise inversion '~' on bool is deprecated and will be removed in Python 3.16. This returns the bitwise inversion of the underlying int object and is usually not what you expect from negating a bool. Use the 'not' operator for boolean negation or ~int(x) if you really want the bitwise inversion of the underlying int.
print(~b)
-1
What's interesting is that there's a test for this:
Lines 68 to 71 in 42d03f3
| with self.assertWarns(DeprecationWarning): | |
| # also check that the warning is issued in case of constant | |
| # folding at compile time | |
| self.assertEqual(eval("~False"), -1) |
eval("~True") is used instead of just ~True
$ python -c 'print(~True)'
-2
$ python -c 'print(eval("~True"))'
<string>:1: DeprecationWarning: Bitwise inversion '~' on bool is deprecated and will be removed in Python 3.16. This returns the bitwise inversion of the underlying int object and is usually not what you expect from negating a bool. Use the 'not' operator for boolean negation or ~int(x) if you really want the bitwise inversion of the underlying int.
-2
CPython versions tested on:
CPython main branch, 3.13
Operating systems tested on:
Linux
Linked PRs
Metadata
Metadata
Assignees
Labels
3.13only security fixesonly security fixes3.14bugs and security fixesbugs and security fixes3.15bugs and security fixesbugs and security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Activity
StanFromIreland commentedon May 19, 2025
It seems to warn for me on 3.15 and 3.14:
This is 3.13 only.
decorator-factory commentedon May 19, 2025
@StanFromIreland I ran it in a container (https://hub.docker.com/_/python/) on 3.14 for reproducibility:
On 3.15 in debug mode, I do get a warning:
EDIT: seems like the warning is displayed in 3.13 and 3.14 if the
-X devflag is enabledAA-Turner commentedon May 20, 2025
cc @timhoffm
timhoffm commentedon May 20, 2025
I will look into this.
serhiy-storchaka commentedon May 31, 2025
This works as intended. By default, DeprecationWarning is only reported for the
__main__module in the Python development mode or in the debug build.Run Python with
-W alwaysor-X devto see them.decorator-factory commentedon May 31, 2025
So in this case, the operation is considered to be in the
__main__modulebut here it's considered to be outside of
__main__?(from the docs (https://docs.python.org/3/library/exceptions.html#DeprecationWarning) and PEP 565 I'm assuming that you meant that deprecation warnings are only active in
__main__by default)
serhiy-storchaka commentedon May 31, 2025
Well, this is obviously related to the fact that
~Trueis calculated at the compile time.If warnings are ignored in the constant folding, this is a bug.
pythongh-134280: Disable constant folding for ~ with a boolean argument
serhiy-storchaka commentedon May 31, 2025
#134982 disables constant folding for
~bool. This moves the deprecation warning from compile time to runtime.Ideally, we could also emit a SyntaxWarning at compile time, like we do for
()(), but this is rather an additional feature with low benefit/cost ratio.We narrowly avoided a bullet with
not NotImplemented.gh-134280: Disable constant folding for ~ with a boolean argument (GH…
pythongh-134280: Disable constant folding for ~ with a boolean argume…
[3.14] gh-134280: Disable constant folding for ~ with a boolean argum…
pythongh-134280: Disable constant folding for ~ with a boolean argume…
pythongh-134280: Disable constant folding for ~ with a boolean argume…
pythongh-134280: Disable constant folding for ~ with a boolean argume…
pythongh-134280: Disable constant folding for ~ with a boolean argume…
pythongh-134280: Disable constant folding for ~ with a boolean argume…