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/