Consider the following class definition:

class Symbolic(object):
    def __eq__(self, rhs):
        return Symbolic()
    def __le__(self, rhs):
        return Symbolic()
    def __gt__(self, rhs):
        return Symbolic()
    def __contains__(self, other):
        return Symbolic()

The operations defined on the class behave like so:

x = Symbolic()
y = Symbolic()

x == y    -->   <Symbolic object at ...>
x <= y    -->   <Symbolic object at ...>
x > y     -->   <Symbolic object at ...>
y in x    -->   True  # huh?

As per the title, my question is: why does the Python runtime explicitly coerce the output of the in operator to a boolean type, but not the output of other comparison operators which are expected to return a boolean value (==, <=, >, etc)?

EDIT: The docs say the following about the in operator and rich comparisons respectively:

  • For user-defined classes which define the __contains__() method, x in y is true if and only if y.__contains__(x) is true.

  • By convention, False and True are returned for a successful comparison. However, these methods can return any value, so if the comparison operator is used in a Boolean context (e.g., in the condition of an if statement), Python will call bool() on the value to determine if the result is true or false.

The question still stands: why is the distinction necessary?

0

There are 0 best solutions below