Discussion:
== on object tests identity in 3.x - summary
Andreas Maier
2014-07-07 23:53:06 UTC
Permalink
Thanks to all who responded.

In absence of class-specific equality test methods, the default
implementations revert to use the identity (=address) of the object as a
basis for the test, in both Python 2 and Python 3.

In absence of specific ordering test methods, the default
implementations revert to use the identity (=address) of the object as a
basis for the test, in Python 2. In Python 3, an exception is raised in
that case.

The bottom line of the discussion seems to be that this behavior is
intentional, and a lot of code depends on it.

We still need to figure out how to document this. Options could be:

1. We define that the default for the value of an object is its
identity. That allows to describe the behavior of the equality test
without special casing such objects, but it does not work for ordering.
Also, I have difficulties stating what constitutes that default case,
because it can really only be explained by referring to the presence or
absence of the class-specific equality test and ordering test methods.

2. We don't say anything about the default value of an object, and
describe the behavior of the equality test and ordering test, which both
need to cover the case that the object does not have the respective test
methods.

It seems to me that only option 2 really works.

Comments and further options welcome.

Andy
Steven D'Aprano
2014-07-08 02:32:34 UTC
Permalink
Post by Andreas Maier
Thanks to all who responded.
In absence of class-specific equality test methods, the default
implementations revert to use the identity (=address) of the object as a
basis for the test, in both Python 2 and Python 3.
Scrub out the "= address" part. Python does not require that objects
even have an address, that is not part of the language definition. (If I
simulate a Python interpreter in my head, what is the address of the
objects?) CPython happens to use the address of objects as their
identity, but that is an implementation-specific trick, not a language
guarantee, and it is documented as such. Neither IronPython nor Jython
use the address as ID.
Post by Andreas Maier
In absence of specific ordering test methods, the default
implementations revert to use the identity (=address) of the object as a
basis for the test, in Python 2.
I don't think that is correct. This is using Python 2.7:

py> a = (1, 2)
py> b = "Hello World!"
py> id(a) < id(b)
True
py> a < b
False

And just to be sure that neither a nor b are controlling this:

py> a.__lt__(b)
NotImplemented
py> b.__gt__(a)
NotImplemented


So the identity of the instances a and b are not used for < , although
the identity of their types may be:

py> id(type(a)) < id(type(b))
False


Using the identity of the instances would be silly, since that would
mean that sorting a list of mixed types would depend on the items'
history, not their values.
Post by Andreas Maier
In Python 3, an exception is raised in that case.
I don't think the ordering methods are terribly relevant to the
behaviour of equals.
Post by Andreas Maier
The bottom line of the discussion seems to be that this behavior is
intentional, and a lot of code depends on it.
I'm not sure it needs to be documented other than to say that the
default object.__eq__ compares by identity. Everything else is, in my
opinion, over-thinking it.
Post by Andreas Maier
1. We define that the default for the value of an object is its
identity. That allows to describe the behavior of the equality test
without special casing such objects, but it does not work for ordering.
Why does it need to work for ordering? Not all values define ordering
relations.

Unlike type and identity, "value" does not have a single concrete
definition, it depends on the class designer. In the case of object, the
value of an object instance is itself, i.e. its identity. I don't think
we need more than that.
--
Steven
Nick Coghlan
2014-07-08 05:23:35 UTC
Permalink
Post by Andreas Maier
Thanks to all who responded.
In absence of class-specific equality test methods, the default
implementations revert to use the identity (=address) of the object as a
basis for the test, in both Python 2 and Python 3.
Post by Andreas Maier
In absence of specific ordering test methods, the default implementations
revert to use the identity (=address) of the object as a basis for the
test, in Python 2. In Python 3, an exception is raised in that case.

In Python 2, it orders by type, and only then by id (which happens to be
the address in CPython).
Post by Andreas Maier
The bottom line of the discussion seems to be that this behavior is
intentional, and a lot of code depends on it.
Post by Andreas Maier
1. We define that the default for the value of an object is its identity.
That allows to describe the behavior of the equality test without special
casing such objects, but it does not work for ordering. Also, I have
difficulties stating what constitutes that default case, because it can
really only be explained by referring to the presence or absence of the
class-specific equality test and ordering test methods.
Post by Andreas Maier
2. We don't say anything about the default value of an object, and
describe the behavior of the equality test and ordering test, which both
need to cover the case that the object does not have the respective test
methods.

The behaviour of Python 3's type system is fully covered by equality
defaulting to comparing by identity, and ordering comparisons having to be
defined explicitly. The docs at
https://docs.python.org/3/reference/expressions.html#not-in could likely be
clarified, but they do cover this (they just cover a lot about the builtins
at the same time).
Post by Andreas Maier
It seems to me that only option 2 really works.
Indeed, and that's the version already documented.

Regards,
Nick.
Post by Andreas Maier
Comments and further options welcome.
Andy
_______________________________________________
Python-Dev mailing list
https://mail.python.org/mailman/listinfo/python-dev
https://mail.python.org/mailman/options/python-dev/ncoghlan%40gmail.com
Loading...