On Tue, Mar 18, 2014 at 1:18 PM, Steven D'Aprano <st...@pearwood.info> wrote: > On Tue, Mar 18, 2014 at 05:05:56AM -0400, Terry Reedy wrote: >> On 3/18/2014 3:52 AM, Maciej Fijalkowski wrote: >> >Hi >> > >> >I have a question about calling __eq__ in some cases. >> > >> >We're thinking about doing an optimization where say: >> > >> >if x in d: >> > return d[x] >> >> if d.__contains__(x): return d.__getitem__(x) > > [Aside: to be pedantic, Python only calls dunder methods on the class, > not the instance, in response to operators and other special calls. That > is, type(d).__contains__ rather than d.__contains__, etc. And to be even > more pedantic, that's only true for new-style classes.] > > >> I do not see any requirement to call x.__eq__ any particular number of >> times. The implementation of d might always call somekey.__eq__(x). The >> concept of sets (and dicts) requires coherent equality comparisons. > > To what extent does Python the language specify that user-defined > classes must be coherent? How much latitude to shoot oneself in the foot > should the language allow? > > What counts as coherent can depend on the types involved. For instance, > I consider IEEE-754 Not-A-Numbers to be coherent, albeit weird. Python > goes only so far to accomodate NANs: while it allows a NAN to test > unequal even to itself (`NAN == NAN` returns False), containers are > allowed to assume that instances are equal to themselves (`NAN in {NAN}` > returns True). This was discussed in great detail a few years ago, and > if I recall correctly, the conclusion was that containers can assume > that their elements are reflexive (they equal themselves), but equality > == cannot make the same assumption and bypass calling __eq__. > > >> >where d is a dict would result in only one dict lookup (the second one >> >being constant folded away). The question is whether it's ok to do it, >> >despite the fact that it changes the semantics on how many times >> >__eq__ is called on x. >> >> A __eq__ that has side-effects violates the intended and expected >> semanitics of __eq__. > > Nevertheless, an __eq__ with side-effects is legal Python and may in > fact be useful. > > It's a tricky one... I don't know how I feel about short-cutting normal > Python semantics for speed. On the one hand, faster is good. But on the > other hand, it makes it harder to reason about code when things go > wrong. "Why is my __eq__ method not being called?" > > > -- > Steven > _______________________________________________ > Python-Dev mailing list > Python-Dev@python.org > https://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: > https://mail.python.org/mailman/options/python-dev/fijall%40gmail.com
note that this is specifically about dicts, where __eq__ will be called undecided number of times anyway (depending on collisions in hash/buckets which is implementation specific to start with) _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com