How to prevent or detect short-circuit evaluation

As others pointed out, the function __and__ is called if the bitwise and operator (&) is used.

The operator and works differently: if bool(a) is True, then the expression a and b evaluates to b, otherwise, it evaluates to a. You cannot change that.

The chained comparization a<=b<=c is defined based on this: it evaluates like (a<=b) and (b<=c) (where b is only evaluated once).

If you do not want that your class is used as an operand to a and b, you can prevent it from being converted to a boolean, which can be done by defining the following member:

     def __bool__(self):
         raise TypeError("Cannot be converted to bool")

By adding this, your testcases yield:

print(a <= b <= c)    # TypeError
print((a <= b) and (b <= c))   # TypeError
print((a <= b) & (b <= c))  #  __and__ is called