not
is implemented through the __nonzero__
special method, which is required to return either True
or False
, so it can’t give the required result. Instead the ~
operator is used, which is implemented through the __not__
special method. For the same reason, &
and |
are used in place of and
and or
.
PEP 335 aimed to allow overloading of boolean operators but was rejected because of excessive overhead (it would e.g. complicate if
statements). PEP 225 suggests a general syntax for “elementwise” operators, which would provide a more general solution, but has been deferred. It appears that the current situation, while awkward, is not painful enough to force change.
np.isfinite
when called on a scalar returns a value of type np.bool_
, not bool
. np.bool_
is also the type you get when extracting a scalar value from an array of bool dtype. If you use np.True_
and np.False_
in place of True
and False
you will get consistent behaviour under ~
.