[Python-Dev] Should the default equality operator compare values instead of identities?

Josiah Carlson jcarlson at uci.edu
Thu Nov 3 02:16:40 CET 2005

Noam Raphael <noamraph at gmail.com> wrote:
> On 11/2/05, Josiah Carlson <jcarlson at uci.edu> wrote:
> > I believe the current behavior of __eq__ is more desireable than
> > comparing contents, as this may result in undesireable behavior
> > (recursive compares on large nested objects are now slow, which used to
> > be fast because default methods wouldn't cause a recursive comparison at
> > all).
> But if the default method doesn't do what you want, it doesn't matter
> how fast it is. Remember that it's very easy to make recursive
> comparisons, by comparing lists for example, and it hasn't disturbed
> anyone.

Right, but lists (dicts, tuples, etc.) are defined as containers, and
their comparison operation is defined on their contents.  Objects are
not defined as containers in the general case, so defining comparisons
based on their contents (as opposed to identity) is just one of the two
assumptions to be made.

I personally like the current behavior, and I see no /compelling/ reason
to change it.  You obviously feel so compelled for the behavior to
change that you are willing to express your desires.  How about you do
something more productive and produce a patch which implements the
changes you want, verify that it passes tests in the standard library,
then post it on sourceforge.  If someone is similarly compelled and
agrees with you (so far I've not seen any public support for your
proposal by any of the core developers), the discussion will restart,
and it will be decided (not by you or I).

> To summarize, I think that value-based equality testing would usually
> be what you want, and currently implementing it is a bit of a pain.

Actually, implementing value-based equality testing, when you have a
finite set of values you want to test, is quite easy.

def __eq__(self, other):
    for i in self.__cmp_eq__:
        if getattr(self, i) != getattr(other, i):
            return False
    return True

With a simple metaclass that discovers all of those values automatically,
and/or your own protocol for exclusion, and you are done.  Remember, not
all 5-line functions should become builtin/default behavior, and this
implementation shows that it is not a significant burdon for you (or
anyone else) to implement this in your own custom library.

 - Josiah

P.S. One thing that you should remember is that even if your patch is
accepted, and even if this is desireable, Python 2.5 is supposed to be
released sometime next year (spring/summer?), and because it is a
backwards incompatible change, would need at least 2.6-2.7 before it
becomes the default behavior without a __future__ import, which is
another 3-4 years down the line.

I understand you are passionate, really I do (you should see some of my
proposals), but by the time these things get around to getting into
mainline Python, there are high odds that you probably won't care about
them much anymore (I've come to feel that way myself about many of my
proposals), and I think it is a good idea to attempt to balance - when
it comes to Python - "Now is better than never." and "Although never is
often better than *right* now."

Removing __hash__, changing __eq__, and trying to get in copy-on-write
freezing (which is really copy-and-cache freezing), all read to me like
"We gotta do this now!", which certainly isn't helping the proposal.

More information about the Python-Dev mailing list