1

Consider this Unknown class:

class Unknown:
    def __add__(self, other):
        return self
    def __radd__(self, other):
        return self

unknown = Unknown()
assert (unknown + 1) is unknown
assert (1 + unknown) is unknown

This also works for __mul__, __rmul__, etc.

However, for Boolean operators e.g.:

assert (unknown or True) is True
assert (unknown or False) is unknown

Attempts such as -

def __or__(self, other):
    return self if not other else other

- or any other combination did not work for me.

Note that I am also unable to define __bool__(self) since it's return value isn't True nor False and returning NotImplemented is not allowed.

So my question: is it possible to override the or, and and operators so that it might return something other than True or False?


Edit: Thanks to @CoryKramer and @Martijn Peters comment below.

I was under the impression that __or__ is for the logical or operator. It is not. It is for the bitwise | and in fact there is no way to override the logical or operator.

Chen Levy
  • 15,438
  • 17
  • 74
  • 92
  • 1
    I'm puzzled by two questions: a) why do you think `(unknown or True) is True` should be `True`, and b) what does "did not work for me" mean exactly? What's the desired result? – timgeb Nov 20 '18 at 12:16
  • 1
    For what it's worth, [PEP 335](https://www.python.org/dev/peps/pep-0335/) proposed allowing overloadable boolean operators a while ago, but it was rejected. – Cory Kramer Nov 20 '18 at 12:18
  • 1
    No, you can't override the boolean logical operators. They evaluate the second argument lazily, and any hook implementation would have to forgo that feature. – Martijn Pieters Nov 20 '18 at 12:21
  • @timgeb: (a) The motivation of such an `Unknown` class is to propagate values in a system when not all of them are known, and to try and limit that unknown state. In the case of `or` operation, since one operator is `True` the result should also be true no matter what the unknown should turn out to be. (b) "Did not work for me" means that the asserts above did not pass. – Chen Levy Nov 20 '18 at 12:25
  • "In the case of or operation, since one operator is True the result should also be true no matter what the unknown should turn out to be" <- In your first assert, Python does not even look at `True`. `bool(unknown)` is `True` so the `or` expression evaluates to `unknown`. E.g. `(unknown or True) is unknown` -> `True`. – timgeb Nov 20 '18 at 12:26

1 Answers1

-1

Why not? Did you try? Seems to work just fine...

class Unknown:
    def __add__(self, other):
        return self
    def __radd__(self, other):
        return self
    def __or__(self, other):
        return self

unknown = Unknown()
assert (unknown or unknown) is unknown
Gijs Wobben
  • 1,974
  • 1
  • 10
  • 13