I actually had some code affected by this.
Ints aren’t only “integers” in Python, they can also be viewed as bitsets representing a subset of U = {0, 1, 2, …}. In theory, any finite or cofinite subset can be so represented. A set S is “cofinite” iff its complement, U-S, is finite. And, in Python, the complement is conveniently spelled as ~S (while U is spelled as ~0 (my preference), or as -1).
Anyway, I had some code with very delicate end conditions. Sometimes the caller wanted to deal with a 0 in the set, but other times it wanted to ignore a 0 (if present). “The obvious” way to write the code was
S &= ~ exclude0
where exclude0 was a bool argument. If False, the RHS evaluates to U, and the intersection is a no-op. If True, the RHS evaluates to the complement of the set containing only 0 (only bit 2**0 == 1), so the intersection clears out the 0 bit regardless of whether it was set.
Obvious to you? Don’t care
. Common? Heck no. Will I live? Heck yes. Was I delighted to change the code? Heck no. Just another low-level irritation to “deal with”.
All computer languages have quirks. Python is, IMO, too mature and widely used now to risk changing much of any visible behaviors, short of screaming bugs, or (but less compellingly so) accidents of implementation that were never documented as “advertised” behavior.
There’s nothing surprising about ~bool to people who learn the language. bool is a subclass of int in Python, period. I don’t give a hoot how it works in other languages. The time for that kind of argument was when Python’s semantics were first crafted. It’s too late for that now.
If some change isn’t worth forking the language for, leave it alone
.