Why are the values of an OrderedDict not equal?

In Python 3, dict.keys() and dict.values() return special iterable classes - respectively a collections.abc.KeysView and a collections.abc.ValuesView. The first one inherit it's __eq__ method from set, the second uses the default object.__eq__ which tests on object identity.


In python3, d1.values() and d2.values() are collections.abc.ValuesView objects:

>>> d1.values()
ValuesView(OrderedDict([('foo', 'bar')]))

Don't compare them as an object, convert them to lists and then compare them:

>>> list(d1.values()) == list(d2.values())
True

Investigating why it works for comparing keys, in _collections_abc.py of CPython, KeysView is inheriting from Set while ValuesView does not:

class KeysView(MappingView, Set):

class ValuesView(MappingView):
  • Tracing for __eq__ in ValuesView and its parents:

    MappingView ==> Sized ==> ABCMeta ==> type ==> object.

    __eq__ is implemented only in object and not overridden.

  • In the other hand, KeysView inherits __eq__ directly from Set.