# Are objects with the same id always equal when comparing them with ==?

Each Answer to this Q is separated by one/two green lines.

If I have two objects o1 and o2, and we know that

``````id(o1) == id(o2)
``````

returns true.

``````o1 == o2
``````

Or is this not always the case? The paper I’m working on says this is not the case, but in my opinion it should be true!

Not always:

``````>>> nan = float('nan')
>>> nan is nan
True
``````

or formulated the same way as in the question:

``````>>> id(nan) == id(nan)
True
``````

but

``````>>> nan == nan
False
``````

NaN is a strange thing. Per definition it is not equal nor less or greater than itself. But it is the same object. More details why all comparisons have to return `False` in this SO question.

The paper is right. Consider the following.

``````class WeirdEquals:
def __eq__(self, other):
return False

w = WeirdEquals()
print("id(w) == id(w)", id(w) == id(w))
print("w == w", w == w)
``````

Output is this:

``````id(w) == id(w) True
w == w False
``````

`id(o1) == id(o2)` does not imply `o1 == o2`.

Let’s have a look at this `Troll` which overrides `__eq__` to always return `False`.

``````>>> class Troll(object):
...     def __eq__(self, other):
...         return False
...
>>> a = Troll()
>>> b = a
>>> id(a) == id(b)
True
>>> a == b
False
``````

That being said, there should be very few examples in the standard library where the object-ids match but `__eq__` can return `False` anyway, kudos @MarkMüller for finding a good example.

So either the objects are insane, very special (like nan), or concurrency bites you. Consider this extreme example, where `Foo` has a more reasonable `__eq__` method (which ‘forgets’ to check the ids) and `f is f` is always `True`.

``````import threading

class Foo(object):
def __init__(self):
self.x = 1

def __eq__(self, other):
return isinstance(other, Foo) and self.x == other.x

f = Foo()

def run(self):
while True:
f.x = 2
f.x = 1

def run(self):
i = 1
while True:
if not (f == f):
print 'loop {0}: f != f'.format(i)
i += 1

``````

Output:

``````\$ python eqtest.py
loop 520617: f != f
loop 1556675: f != f
loop 1714709: f != f
loop 2436222: f != f
loop 3210760: f != f
loop 3772996: f != f
loop 5610559: f != f
loop 6065230: f != f
loop 6287500: f != f
...
`````` The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .