~bool deprecation

What about deprecating ~bool for a while but with the intention to make it work properly in the end rather than just removing it altogether?

The use of ~ for logical negation is widespread e.g. numpy:

In [11]: a = np.array([1, 2, 3, 4])

In [12]: cond = a % 2 == 0

In [13]: cond
Out[13]: array([False,  True, False,  True])

In [14]: ~cond
Out[14]: array([ True, False,  True, False])

In [15]: a[~cond] = -1

In [16]: a
Out[16]: array([-1,  2, -1,  4])

Also sympy:

In [17]: import sympy

In [18]: x, y, z = sympy.symbols('x, y, z')

In [19]: cond = x & (y | ~z)

In [20]: cond
Out[20]: x ∧ (y ∨ ¬z)

In [21]: cond.subs(z, True)
Out[21]: x ∧ y

In [34]: x | ~sympy.S.true
Out[34]: x

In [35]: x | ~True
---------------------------------------------------------------------------
TypeError

Many more examples of libraries using these can be found. The ones I know of all broadly correspond to the above two cases though: arrays of booleans or symbolic boolean expressions.

Ultimately it would be better if bool was not a subclass of int. Having it be a subclass of int now does create a compatibility problem for any change because of e.g. if isinstance(obj, int): return ~obj but I doubt that a lot of code depends on ~bool given how useless it is: just use an int if you want an int! Even ~int is rarely needed in Python and I can’t imagine doing that in some context where bools and ints are mixed so that I’m going to do ~obj without knowing where obj is an int or not.

A future non-int bool type could still support arithmetic operations like True - True -> 0 for compatibility but could do the right thing for operators like ~ that might reasonably be expected to handle boolean logic properly.

9 Likes