[Python-Dev] PyObject_RichCompareBool identity shortcut

Terry Reedy tjreedy at udel.edu
Thu Apr 28 21:30:58 CEST 2011


On 4/28/2011 6:11 AM, Nick Coghlan wrote:
> On Thu, Apr 28, 2011 at 6:30 PM, Alexander Belopolsky
> <alexander.belopolsky at gmail.com>  wrote:
>> On Thu, Apr 28, 2011 at 3:57 AM, Nick Coghlan<ncoghlan at gmail.com>  wrote:
>> ..
>>>> It is an interesting question of what "sane invariants" are.  Why you
>>>> consider the invariants that you listed essential while say
>>>>
>>>> if c1 == c2:
>>>>    assert all(x == y for x,y in zip(c1, c2))
>>>>
>>>> optional?
>>>
>>> Because this assertion is an assertion about the behaviour of
>>> comparisons that violates IEEE754, while the assertions I list are all
>>> assertions about the behaviour of containers that can be made true
>>> *regardless* of IEEE754 by checking identity explicitly.
>>>
>>
>> AFAIK, IEEE754 says nothing about comparison of containers, so my
>> invariant cannot violate it.  What you probably wanted to say is that
>> my invariant cannot be achieved in the presence of IEEE754 conforming
>> floats, but this observation by itself does not make my invariant less
>> important than yours.  It just makes yours easier to maintain.
>
> No, I meant what I said. Your assertion includes a direct comparison
> between values (the "x == y" part) which means that IEEE754 has a
> bearing on whether or not it is a valid assertion. Every single one of
> my stated invariants consists solely of relationships between
> containers, or between a container and its contents. This keeps them
> all out of the domain of IEEE754 since the *container implementers*
> get to decide whether or not to factor object identity into the
> management of the container contents.
>
> The core containment invariant is really only this one:
>
>      for x in c:
>          assert x in c
>
> That is, if we iterate over a container, all entries returned should
> be in the container. Hopefully it is non-controversial that this is a
> sane and reasonable invariant for a container *user* to expect.
>
> The comparison invariants follow from the definition of set equivalence as:
>
>    set1 == set2 iff all(x in set2 for x in set1) and all(y in set1 for y in set2)
>
> Again, notice that there is no comparison of items here - merely a
> consideration of the way items relate to containers.

I agree that the container (author) gets to define container equality. 
The definition should also be correctly documented.

5.9. Comparisons says "Tuples and lists are compared lexicographically 
using comparison of corresponding elements. This means that to compare 
equal, each element must compare equal and the two sequences must be of 
the same type and have the same length.". This, I believe is the same as 
what Hrvoje said "I would expect l1 == l2, where l1 and l2 are both 
lists, to be semantically equivalent to len(l1) == len(l2) and 
all(imap(operator.eq, l1, l2))."

But "Currently it isn't, and that was the motivation for this thread." 
In this case, I think the discrepancy should be fixed by changing the 
doc. Add 'be identical or ' before 'compare equal'.

-- 
Terry Jan Reedy



More information about the Python-Dev mailing list