# [Python-ideas] Changing the meaning of bool.__invert__

Steven D'Aprano steve at pearwood.info
Thu Apr 7 07:04:25 EDT 2016

```On Thu, Apr 07, 2016 at 09:46:18AM +0200, Antoine Pitrou wrote:
>
> Hello,
>
> Booleans currently have reasonable overrides for the bitwise binary
> operators:
>
> >>> True | False
> True
> >>> True & False
> False
> >>> True ^ False
> True

Substitute 1 for True and 0 for False, and these results are exactly the
same as the bitwise operations on ints. And that works since True is
defined to equal 1 and False to equal 0.

> However, the same cannot be said of bitwise unary complement, which
> returns rather useless integer values:
>
> >>> ~False
> -1
> >>> ~True
> -2

Substitute 0 for False and 1 for True, and you get exactly the same
results. What else did you expect from bitwise-not?

> Numpy's boolean type does the more useful (and more expected) thing:
>
> >>> ~np.bool_(True)
> False

Expected by whom? I wouldn't expect bitwise-not to be the same as binary
not. If I want binary not, I'll spell it `not`.

> How about changing the behaviour of bool.__invert__ to make it in line
> with the Numpy boolean?
> (i.e. bool.__invert__ == operator.not_)

Why? What problem does this solve? We already have a perfectly good way
of spelling binary not, why break backwards compatibility to get a
second way to spell it?

It also breaks a fundamental property of most mathematical relations:

if a == b, then f(a) == f(b)

(assuming f(a) and f(b) are defined for the type of both a and b).

That is currently true for bools:

py> (True == 1) and (~True == ~1)
True
py> (False==0) and (~False == ~0)
True

You want ~b to return `not b`:

py> (True == 1) and (False == ~1)
False
py> (False==0) and (True == ~0)
False

I see no upside and a serious downside to this proposal.

--
Steve
```