0

Seeing as dict_values has been the only builtin subclass of abc.Hashable which has a broken __eq__ method I've ran into so far, it makes me think it's a bug. While this issue is something most people will never encounter, if I didn't set my tests up just right for my pickleable lru cache I'm making, I would have missed this.

Not only is it illogical, it is confusing to beginners because for all other builtin containers whose __repr__ compares equal, the objects compare equal. The following results are identical in versions 3.3, 3.4, 3.5, and 3.6: (and even in the pure python version of collections.OrderedDict from 3.3).

>>> a = {1:1}
>>> b = {1:1}
>>> a == b
True
>>> a.items() == b.items()
True
>>> a.keys() == b.keys()
True
>>> a.values() == b.values()
False
>>> x, y = a.values(), b.values()
>>> x == y
False
>>> list(a.values()) == list(b.values())
True
>>> blank = {}
>>> for i in range(10):
        blank[{}.values()] = i      
>>> blank
{dict_values([]): 0, dict_values([]): 1, dict_values([]): 2, dict_values([]): 3, dict_values([]): 4, dict_values([]): 5, dict_values([]): 6, dict_values([]): 7, dict_values([]): 8, dict_values([]): 9}
falsetru
  • 357,413
  • 63
  • 732
  • 636
bup
  • 113
  • 6
  • Briefly: it's undefined, so you get identity. ¯\\_(ツ)\_/¯ – TigerhawkT3 Mar 05 '17 at 03:40
  • @TigerhawkT3 I'm not sure this is an exact duplicate, OP has a reasonable point that it works fine for `keys()` and `items()`, but not `values()` (despite all three being similar `dict_` iterables) – anthony sottile Mar 05 '17 at 04:49
  • @AnthonySottile - The key is that it happens to be undefined, and that's what happens in that case. – TigerhawkT3 Mar 05 '17 at 04:56
  • 1
    Sure, though in this case the answer seems [more](https://github.com/python/cpython/commit/b90c84889eb1d98957dc80c0420df41d6ce32e40) [interesting](https://github.com/python/cpython/commit/d9214d1f2cd9402e98c14809d17076e5f1db4167) and perhaps an oversight and should be opened as a bug. – anthony sottile Mar 05 '17 at 05:06
  • @AnthonySottile it isn't a bug, there's been discussion about this on the mailing list. Take a look at my answer [here](http://stackoverflow.com/a/41231725/4952130). OP, this should answer your question too, I'll add it as the duplicate now. – Dimitris Fasarakis Hilliard Mar 05 '17 at 12:12
  • @JimFasarakis-Hilliard Much better! Thanks for that awesome answer! – anthony sottile Mar 05 '17 at 16:44
  • @AnthonySottile I read your post and it makes sense now. Or at least it did before 3.6. I had already forgotten that dicts used to be random, which meant that you can't convert `dict_items` to a list and expect it to compare equal to a list of another dict's keys, even if they had the same length and same contents. It would be a bad idea to make `OrderedDicts` behave differently in the regard because it's not obvious. Guess I'll have to use my ugly and inefficient implementation until we get a builtin multiset. – bup Mar 06 '17 at 00:59

0 Answers0