In the sense of “can we accomplish this with an expression?”, either works. Neither is a simple binary operator that directly takes two boolean values and gives the desired result, though, so we have fourteen out of sixteen. Though since some of them are somewhat degenerate cases, I think it’s not unreasonable to say that, out of the sixteen possibilities, six are easier than binary operators (False and True as constants, and p, q, not p, and not q which require only one operand), and then we have two that are notably more complicated (nand and nor, in either of the valid spellings). The remaining eight are correctly identified as simple binary operators, although of course they don’t all have the same meaning if given values that aren’t strictly booleans.

So that’s half of the available options as binary operators, and nearly all the rest as something even simpler.

Yes, because bool is implemented as a subclass of int, and False == 0, True == 1. If True == -1, the boolean implication operation would be written as p >= q, which is less confusing. We could even introduce => as an alias of >=.

It could also solve an issue with the ~ operator. ~p would be equal to not p. Currently the result of ~p is not representable as a bool.

But making True == -1 would break a lot of existing code. Maybe in Python 4…