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 ify.__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?