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/archive%40mail-archive.com