On Fri, Jan 24, 2020 at 10:57:11PM +1100, Chris Angelico wrote:
> On Fri, Jan 24, 2020 at 10:44 PM Steven D'Aprano <[email protected]> wrote:
> >
> > The only thing I'm unsure of here is whether direct use of the `==` and
> > `!=` operators are included as "implicit calls" to the dunders. I
> > *think* I understand Guido's intention, but I'm not sure:
> >
> > * x == y MUST call `__eq__`
> >
> > * likewise x != y MUST call `__ne__`
Oh, that's too strong. The interpreter ought to be allowed to bypass the
method call if it is knows that reflexivity certainly holds.
Obviously it can't know that in the general case of two arbitrary
objects, but if the interpreter knows that both objects are a built-in
type (not a subclass) apart from float, then it *might* choose to test
for identity.
In other words, atomic objects MUST NOT *assume* reflexivity[1] of
arbitrary types, but MAY take advantage of reflexivity of specific known
types.
(E.g. ints don't have NANs, so there's no harm in allowing the
interpreter to skip the method call if it knows both operands are actual
built-in ints.)
> > * but compound objects such as lists and other collections MAY skip
> > calling `__eq__` (or `__eq__`) on their component parts.
Whereas compound objects MAY assume reflexivity of their component
parts.
> Are there any non-container uses where this comes up?
"Container" is an ABC, whereas I'm being more general and talking about
any compound object that might wish to short-cut long, possibly
recursive equality tests.
For instance, SimpleNamespace supports equality:
x = SimpleNamespace(a=1, b=2)
y = SimpleNamespace(a=1, b=2)
x == y # returns True
Testing for equality of the values can be as expensive as you want. But
`SimpleNamespace.__eq__` should be entitled to assume that:
- if both operands are the same SimpleNamespace object, they are equal;
- for any name binding in the Simplenamespace (like a=1 or b=2),
if the values in the two operands are the same object, the values
are also equal (i.e. equality is reflexive).
> Can the rule be
> codified simply as that container membership, in all core/stdlib
> types, is defined by "x is y or x == y"?
I can't personally think of any other optimization that is likely to
work. But if somebody did think of one, shouldn't they be entitled to
use it?
[1] Reflexivity of an operator (e.g. equality) means that x == x for any
value of x.
--
Steven
_______________________________________________
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/7NMEKJQDNGRWI3CR24Q5GK63JBXJRSGM/
Code of Conduct: http://python.org/psf/codeofconduct/