Set "in" operator: uses equality or identity?

Gennadiy Rozental picture Gennadiy Rozental · Feb 1, 2012 · Viewed 8.7k times · Source
class A(object):
    def __cmp__(self):
        print '__cmp__'
        return object.__cmp__(self)

    def __eq__(self, rhs):
        print '__eq__'
        return True
a1 = A()
a2 = A()
print a1 in set([a1])
print a1 in set([a2])

Why does first line prints True, but second prints False? And neither enters operator eq?

I am using Python 2.6

Answer

Raymond Hettinger picture Raymond Hettinger · Feb 1, 2012

Set __contains__ makes checks in the following order:

 'Match' if hash(a) == hash(b) and (a is b or a==b) else 'No Match'

The relevant C source code is in Objects/setobject.c::set_lookkey() and in Objects/object.c::PyObject_RichCompareBool().