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 <st...@pearwood.info> 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 -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/7NMEKJQDNGRWI3CR24Q5GK63JBXJRSGM/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to