[Python-ideas] Fwd: Why do equality tests between OrderedDict keys/values views behave not as expected?
Steven D'Aprano
steve at pearwood.info
Fri Dec 18 23:10:11 EST 2015
On Fri, Dec 18, 2015 at 10:43:24PM -0500, Franklin? Lee wrote:
> On Fri, Dec 18, 2015 at 10:38 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> > On Fri, Dec 18, 2015 at 05:59:39PM -0500, Franklin? Lee wrote:
> >
> >> I see two options:
> >> - comparison is explicitly NotImplemented. Any code that used it
> >> should've used `is`.
> >
> > We're still talking about equality between Mapping.values() views,
> > correct?
[...]
> First, failing fast. I see this as a silent error waiting to happen.
Franklin, could you please try to be a little bit more explicit about
what "it" and "this" is when you describe something? I find it very hard
to understand what *specific* thing you are referring to when you refer
to it using short-hand.
You say that "this" is a silent error waiting to happen. Does "this"
refer to your suggestion that "comparison is explicitly NotImplemented",
or something else? I can't tell.
> Second, "NotImplemented" allows the other side to try its __eq__.
Okay, that makes better sense. I tought you meant that
Mapping.ValuesView *did not implement* an __eq__ method, so that it
raised an exception if you tried to compare them:
# What I thought you meant
a.values() == b.values()
=> raises an exception
Now I understand that you mean they should return NotImplemented
instead. But in practice, that doesn't actually change the behaviour
that much: if both sides return NotImplemented, Python will fall back to
the default behaviour, which is identity.
py> class A:
... def __eq__(self, other):
... return NotImplemented
...
py> a = A()
py> b = A()
py> a == a
True
py> a == b
False
Returning NotImplemented just allows the other argument a chance to be
called, but that already happens!
py> class Spam:
... def __eq__(self, other):
... print("calling Spam.__eq__")
... return True
...
py> a = odict()
py> b = Spam()
py> a == b
calling Spam.__eq__
True
py> b == a
calling Spam.__eq__
True
So no change there. We already have that behaviour.
--
Steve
More information about the Python-ideas
mailing list