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

Reply via email to