This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Comparison of OrderedDict() and dict()
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.10, Python 3.9
process
Status: closed Resolution: wont fix
Dependencies: Superseder:
Assigned To: Nosy List: rhettinger, socketpair
Priority: normal Keywords:

Created on 2021-04-01 09:42 by socketpair, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (6)
msg389965 - (view) Author: Марк Коренберг (socketpair) * Date: 2021-04-01 09:42
OrderedDict([(1,2), (3,4)]) == OrderedDict([(3,4), (1,2)])
Out[1]: False    # OK

dict([(1,2), (3,4)]) == dict([(3,4), (1,2)])
Out[2]: True     # OK

dict([(1,2), (3,4)]) == OrderedDict([(3,4), (1,2)])
Out[3]: True     # NOT OK, since actual order is different

OrderedDict([(1,2), (3,4)]) == dict([(3,4), (1,2)])
Out[4]: True     # NOT OK, since actual orderd is different


I propose two options to fix it:

1. Return True when comparing anything with OrderedDict iff order is the same.
2. Raise TypeError when someone tries to compare OrderedDict() and dict(). # I think it's better.
msg389999 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2021-04-01 16:59
Unfortunately, the existing behaviors are guaranteed and cannot be changing without breaking code — the OrderedDict class was designed to be mostly substitutable for regular dicts in existing code.

Personally, I think it would have been better if OrderedDict equality always worked the same way a dict equality, but I was overruled and that ship sailed long ago.  It is what it is.
msg390027 - (view) Author: Марк Коренберг (socketpair) * Date: 2021-04-02 02:13
I don't agree. There are no specifications regarding the question. Since anything relying on specific implementation (not specification) should not be considered as something we should support or take care of.

Raising exception is the best thing since it will show real bug in applications.
msg390028 - (view) Author: Марк Коренберг (socketpair) * Date: 2021-04-02 02:16
https://mail.python.org/pipermail/python-ideas/2015-December/037472.html
msg390029 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2021-04-02 02:41
> There are no specifications regarding the question.

From the OrderedDict docs:

"""
Equality tests between OrderedDict objects are order-sensitive and are implemented as list(od1.items())==list(od2.items()). Equality tests between OrderedDict objects and other Mapping objects are order-insensitive like regular dictionaries. This allows OrderedDict objects to be substituted anywhere a regular dictionary is used.
"""

Also, there are tests to verify these behaviors.  From Lib/test/test_ordered_dict.py:

    def test_equality(self):
        OrderedDict = self.OrderedDict
        pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
        shuffle(pairs)
        od1 = OrderedDict(pairs)
        od2 = OrderedDict(pairs)
        self.assertEqual(od1, od2)          # same order implies equality
        pairs = pairs[2:] + pairs[:2]
        od2 = OrderedDict(pairs)
        self.assertNotEqual(od1, od2)       # different order implies inequality
        # comparison to regular dict is not order sensitive
        self.assertEqual(od1, dict(od2))
        self.assertEqual(dict(od2), od1)
        # different length implied inequality
        self.assertNotEqual(od1, OrderedDict(pairs[:-1]))



> Raising exception is the best thing since it will show 
> real bug in applications.

Changing the implementation now will break correct code that relies the documented behavior.  The change would also violate an intentional day one design goal to have ordered dictionaries be substitutable for regular dicts in existing code that may not have any concept of order.  Per PEP 372:

"""
Is the ordered dict a dict subclass? Why?

Yes. Like defaultdict, an ordered dictionary subclasses dict. Being a dict subclass make some of the methods faster (like __getitem__ and __len__). More importantly, being a dict subclass lets ordered dictionaries be usable with tools like json that insist on having dict inputs by testing isinstance(d, dict)
"""



> I don't agree.

That's not relevant.  The time to debate the merits of this API passed 13 years ago.  Guido made the final decision on the equality logic.  And now that the code is deployed and widely adopted, it is far too late to change it.
msg390030 - (view) Author: Марк Коренберг (socketpair) * Date: 2021-04-02 02:48
Shame on me. You are right.
History
Date User Action Args
2022-04-11 14:59:43adminsetgithub: 87857
2021-04-02 02:48:50socketpairsetstatus: open -> closed
resolution: wont fix
messages: + msg390030
2021-04-02 02:41:53rhettingersetmessages: + msg390029
2021-04-02 02:16:11socketpairsetmessages: + msg390028
2021-04-02 02:13:32socketpairsetstatus: closed -> open
resolution: not a bug -> (no value)
messages: + msg390027
2021-04-01 16:59:51rhettingersetstatus: open -> closed

nosy: + rhettinger
messages: + msg389999

resolution: not a bug
stage: resolved
2021-04-01 09:42:56socketpaircreate