[pypy-issue] Issue #2352: list.__contains__ compares objects in wrong order (pypy/pypy)
issues-reply at bitbucket.org
Sat Jul 23 07:37:06 EDT 2016
New issue 2352: list.__contains__ compares objects in wrong order
Consider the following program:
def __init__(self, bar):
self.bar = bar
return 'Foo(%r)' % (self.bar,)
def __eq__(self, other):
print('Foo.__eq__(%r, %r)' % (self, other))
return self.bar == other
foo1 = Foo('A')
foo2 = Foo('B')
assert foo1 not in [foo2]
Under CPython 2.7.11 and 3.5.1, it prints:
But under PyPy 5.3.1 (2.7), it prints:
PyPy’s behavior contradicts the [Python 2 language reference](https://docs.python.org/2/reference/expressions.html#membership-test-details):
> For the list and tuple types, `x in y` is true if and only if there exists an index *i* such that either `x is y[i]` or `x == y[i]` is true.
According to the [Python 3 language reference](https://docs.python.org/3/reference/expressions.html#value-comparisons) (can’t find anything about this in Python 2), equality does not have to be symmetric (emphasis mine):
> User-defined classes that customize their comparison behavior should follow some consistency rules, **if possible**:
> . . .
> * Comparison should be symmetric
> . . .
> Python does not enforce these consistency rules. In fact, the not-a-number values are an example for not following these rules.
In my case, `x` and `y` are instances of different classes with completely different, magical `__eq__`, so this becomes important.
More information about the pypy-issue