[Python-Dev] == on object tests identity in 3.x
While discussing Python issue #12067
(http://bugs.python.org/issue12067#msg222442), I learned that Python 3.4
implements '==' and '!=' on the object type such that if no special
equality test operations are implemented in derived classes, there is a
default implementation that tests for identity (as opposed to equality
of the values).
The relevant code is in function do_richcompare() in Objects/object.c.
IMHO, that default implementation contradicts the definition that '=='
and '!=' test for equality of the values of an object.
Python 2.x does not seem to have such a default implementation; == and
!= raise an exception if attempted on objects that don't implement
equality in derived classes.
I'd like to gather comments on this issue, specifically:
-> Can someone please elaborate what the reason for that is?
-> Where is the discrepancy between the documentation of == and its
default implementation on object documented?
To me, a sensible default implementation for == on object would be (in
Python):
if v is w:
return True;
elif type(v) != type(w):
return False
else:
raise ValueError("Equality cannot be determined in default
implementation")
Andy
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] == on object tests identity in 3.x
On Mon, Jul 7, 2014, at 04:22, Andreas Maier wrote: > While discussing Python issue #12067 > (http://bugs.python.org/issue12067#msg222442), I learned that Python 3.4 > implements '==' and '!=' on the object type such that if no special > equality test operations are implemented in derived classes, there is a > default implementation that tests for identity (as opposed to equality > of the values). > > The relevant code is in function do_richcompare() in Objects/object.c. > > IMHO, that default implementation contradicts the definition that '==' > and '!=' test for equality of the values of an object. > > Python 2.x does not seem to have such a default implementation; == and > != raise an exception if attempted on objects that don't implement > equality in derived classes. Why do you think that? % python Python 2.7.6 (default, May 29 2014, 22:22:15) [GCC 4.7.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> class x(object): pass ... >>> class y(object): pass ... >>> x != y True >>> x == y False ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] == on object tests identity in 3.x
On Tue, Jul 8, 2014 at 1:15 AM, Benjamin Peterson wrote: > Why do you think that? > > % python > Python 2.7.6 (default, May 29 2014, 22:22:15) > [GCC 4.7.3] on linux2 > Type "help", "copyright", "credits" or "license" for more information. class x(object): pass > ... class y(object): pass > ... x != y > True x == y > False Your analysis is flawed - you're testing the equality of the types, not of instances. But your conclusion's correct; testing instances does work the same way you're implying: rosuav@sikorsky:~$ python Python 2.7.3 (default, Mar 13 2014, 11:03:55) [GCC 4.7.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> class x(object): pass ... >>> class y(object): pass ... >>> x() != y() True >>> x() == y() False >>> x() == x() False >>> z = x() >>> z == z True ChrisA ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] buildbot.python.org down again?
It would still be nice to know who "the appropriate persons" are. Too much of our infrastructure seems to be maintained by house elves or the ITA. On Sun, Jul 6, 2014 at 11:33 PM, Terry Reedy wrote: > On 7/6/2014 7:54 PM, Ned Deily wrote: > >> As of the moment, buildbot.python.org seems to be down again. >> > > Several hours later, back up. > > > > Where is the best place to report problems like this? > > We should have, if not already, an automatic system to detect down servers > and report (email) to appropriate persons. > > -- > Terry Jan Reedy > > > ___ > Python-Dev mailing list > [email protected] > https://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: https://mail.python.org/mailman/options/python-dev/ > guido%40python.org > -- --Guido van Rossum (python.org/~guido) ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] == on object tests identity in 3.x
Am 07.07.2014 17:15, schrieb Benjamin Peterson: On Mon, Jul 7, 2014, at 04:22, Andreas Maier wrote: Python 2.x does not seem to have such a default implementation; == and != raise an exception if attempted on objects that don't implement equality in derived classes. Why do you think that? Because I looked at the source code of try_rich_compare() in object.c of the 2.7 stream in the repository. Now, looking deeper into that module, it turns out there is a whole number of variations of comparison functions, so maybe I looked at the wrong one. Instead of trying to figure out how they are called, it is probably easier to just try it out, as you did. Your example certainly shows that == between instances of type object returns a value. So the Python 2.7 implementation shows the same discrepancy as Python 3.x regarding the == and != default implementation. Does anyone know why? Andy ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] buildbot.python.org down again?
On Mon, Jul 7, 2014, at 08:44, Guido van Rossum wrote: > It would still be nice to know who "the appropriate persons" are. Too > much > of our infrastructure seems to be maintained by house elves or the ITA. :) Is ITA "International Trombone Association"? ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] == on object tests identity in 3.x
On 2014-07-07, at 13:22 , Andreas Maier wrote:
> While discussing Python issue #12067
> (http://bugs.python.org/issue12067#msg222442), I learned that Python 3.4
> implements '==' and '!=' on the object type such that if no special equality
> test operations are implemented in derived classes, there is a default
> implementation that tests for identity (as opposed to equality of the values).
>
> The relevant code is in function do_richcompare() in Objects/object.c.
>
> IMHO, that default implementation contradicts the definition that '==' and
> '!=' test for equality of the values of an object.
>
> Python 2.x does not seem to have such a default implementation; == and !=
> raise an exception if attempted on objects that don't implement equality in
> derived classes.
That's incorrect on two levels:
1. What Terry notes in the bug comments is that because all Python 3
types inherit from object this can be done as a default __eq__/__ne__,
in Python 2 the fallback is encoded in the comparison framework
(PyObject_Compare and friends):
http://hg.python.org/cpython/file/01ec8bb7187f/Objects/object.c#l756
2. Unless comparison methods are overloaded and throw an error it will
always return either True or False (for comparison operator), never throw.
> I'd like to gather comments on this issue, specifically:
>
> -> Can someone please elaborate what the reason for that is?
>
> -> Where is the discrepancy between the documentation of == and its default
> implementation on object documented?
>
> To me, a sensible default implementation for == on object would be (in
> Python):
>
> if v is w:
>return True;
> elif type(v) != type(w):
>return False
> else:
>raise ValueError("Equality cannot be determined in default implementation")
Why would comparing two objects of different types return False but
comparing two objects of the same type raise an error?
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] == on object tests identity in 3.x
Am 07.07.2014 17:58, schrieb Xavier Morel:
On 2014-07-07, at 13:22 , Andreas Maier wrote:
While discussing Python issue #12067
(http://bugs.python.org/issue12067#msg222442), I learned that Python 3.4
implements '==' and '!=' on the object type such that if no special equality
test operations are implemented in derived classes, there is a default
implementation that tests for identity (as opposed to equality of the values).
The relevant code is in function do_richcompare() in Objects/object.c.
IMHO, that default implementation contradicts the definition that '==' and '!='
test for equality of the values of an object.
Python 2.x does not seem to have such a default implementation; == and != raise
an exception if attempted on objects that don't implement equality in derived
classes.
That's incorrect on two levels:
1. What Terry notes in the bug comments is that because all Python 3
types inherit from object this can be done as a default __eq__/__ne__,
in Python 2 the fallback is encoded in the comparison framework
(PyObject_Compare and friends):
http://hg.python.org/cpython/file/01ec8bb7187f/Objects/object.c#l756
2. Unless comparison methods are overloaded and throw an error it will
always return either True or False (for comparison operator), never throw.
I was incorrect for Python 2.x.
I'd like to gather comments on this issue, specifically:
-> Can someone please elaborate what the reason for that is?
-> Where is the discrepancy between the documentation of == and its default
implementation on object documented?
To me, a sensible default implementation for == on object would be (in Python):
if v is w:
return True;
elif type(v) != type(w):
return False
else:
raise ValueError("Equality cannot be determined in default implementation")
Why would comparing two objects of different types return False
Because I think (but I'm not sure) that the type should play a role for
comparison of values. But maybe that does not embrace duck typing
sufficiently, and the type should be ignored by default for comparing
object values.
> but comparing two objects of the same type raise an error?
That I'm sure of: Because the default implementation (after having
exhausted all possibilities of calling __eq__ and friends) has no way to
find out whether the values(!!) of the objects are equal.
Andy
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] == on object tests identity in 3.x
On 07/07/2014 04:22 AM, Andreas Maier wrote: Where is the discrepancy between the documentation of == and its default implementation on object documented? There's seems to be no discrepancy (at least, you have not shown it), but to answer the question about why the default equals operation is an identity test: - all objects should be equal to themselves (there is only one that isn't, and it's weird) - equality tests should not, as a general rule, raise exceptions -- they should return True or False -- ~Ethan~ ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] == on object tests identity in 3.x
Am 07.07.2014 17:55, schrieb Ethan Furman: On 07/07/2014 04:22 AM, Andreas Maier wrote: Where is the discrepancy between the documentation of == and its default implementation on object documented? There's seems to be no discrepancy (at least, you have not shown it), The documentation states consistently that == tests the equality of the value of an object. The default implementation of == in both 2.x and 3.x tests the object identity. Is that not a discrepancy? but to answer the question about why the default equals operation is an identity test: - all objects should be equal to themselves (there is only one that isn't, and it's weird) I agree. But that is not a reason to conclude that different objects (as per their identity) should be unequal. Which is what the default implementation does. - equality tests should not, as a general rule, raise exceptions -- they should return True or False Why not? Ordering tests also raise exceptions if ordering is not implemented. Andy ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] buildbot.python.org down again?
It's a reference to Neil Stephenson's Anathem. On Jul 7, 2014 8:55 AM, "Benjamin Peterson" wrote: > On Mon, Jul 7, 2014, at 08:44, Guido van Rossum wrote: > > It would still be nice to know who "the appropriate persons" are. Too > > much > > of our infrastructure seems to be maintained by house elves or the ITA. > > :) Is ITA "International Trombone Association"? > ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] buildbot.python.org down again?
Le 07/07/2014 13:22, Guido van Rossum a écrit : It's a reference to Neil Stephenson's Anathem. According to Google, it doesn't look like he played the trombone, though. Regards Antoine. On Jul 7, 2014 8:55 AM, "Benjamin Peterson" mailto:[email protected]>> wrote: On Mon, Jul 7, 2014, at 08:44, Guido van Rossum wrote: > It would still be nice to know who "the appropriate persons" are. Too > much > of our infrastructure seems to be maintained by house elves or the ITA. :) Is ITA "International Trombone Association"? ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] == on object tests identity in 3.x
On 07/07/2014 09:56 AM, Andreas Maier wrote: Am 07.07.2014 17:55, schrieb Ethan Furman: On 07/07/2014 04:22 AM, Andreas Maier wrote: Where is the discrepancy between the documentation of == and its default implementation on object documented? There's seems to be no discrepancy (at least, you have not shown it), The documentation states consistently that == tests the equality of the value of an object. The default implementation of == in both 2.x and 3.x tests the object identity. Is that not a discrepancy? One could say that the value of an object is the object itself. Since different objects are different, then they are not equal. but to answer the question about why the default equals operation is an identity test: - all objects should be equal to themselves (there is only one that isn't, and it's weird) I agree. But that is not a reason to conclude that different objects (as per their identity) should be unequal. Which is what the default implementation does. Python cannot know which values are important in an equality test, and which are not. So it refuses to guess. Think of a chess board, for example. Are any two black pawns equal? All 16 pawns came from the same Pawn class, the only differences would be in the color and position, but the movement type is the same for all. So equality for a pawn might mean the same color, or it might mean color and position, or it might mean can move to the same position... it's up to the programmer to decide which of the possibilities is the correct one. Quite frankly, have equality mean identity in this case also makes a lot of sense. - equality tests should not, as a general rule, raise exceptions -- they should return True or False Why not? Ordering tests also raise exceptions if ordering is not implemented. Besides the pawn example, this is probably a matter of practicality over purity -- equality tests are used extensively through-out Python, and having exceptions raised at possibly any moment would not be a fun nor productive environment. Ordering is much less frequent, and since we already tried always ordering things, falling back to type name if necessary, we have discovered that that is not a good trade-off. So now if one tries to order things without specifying how it should be done, one gets an exception. -- ~Ethan~ ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] == on object tests identity in 3.x
On 7/7/2014 7:22 AM, Andreas Maier wrote: While discussing Python issue #12067 (http://bugs.python.org/issue12067#msg222442), I learned that Python 3.4 implements '==' and '!=' on the object type such that if no special equality test operations are implemented in derived classes, there is a default implementation that tests for identity (as opposed to equality of the values). The relevant code is in function do_richcompare() in Objects/object.c. IMHO, that default implementation contradicts the definition that '==' and '!=' test for equality of the values of an object. A discrepancy between code and doc can be solved by changing either the code or doc. This is a case where the code should not change (for back compatibility with long standing behavior, if nothing else) and the doc should. -- Terry Jan Reedy ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Tracker Stats
On 06/23/2014 10:12 PM, R. David Murray wrote: The stats graphs are based on the data generated for the weekly issue report. I have a patched version of that report that adds the bug/enhancement info. I'll try to dig it up this week; someone ping me if I forget :) It think the patch will need to be updated based on Ezio's changes. ping ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Tracker Stats
On 07/07/2014 12:01 PM, francis wrote: On 06/23/2014 10:12 PM, R. David Murray wrote: The stats graphs are based on the data generated for the weekly issue report. I have a patched version of that report that adds the bug/enhancement info. I'll try to dig it up this week; someone ping me if I forget :) It think the patch will need to be updated based on Ezio's changes. ping pong ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] == on object tests identity in 3.x
On 07/07/2014 08:29 AM, Andreas Maier wrote: So the Python 2.7 implementation shows the same discrepancy as Python 3.x regarding the == and != default implementation. Why do you see this as a discrepancy? Just because two instances from the same object have the same value does not mean they are equal. For a real-life example, look at twins: biologically identical, yet not equal. looking-forward-to-the-rebuttal-mega-thread'ly yrs, -- ~Ethan~ ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] == on object tests identity in 3.x
07.07.2014 18:11, Andreas Maier wrote:
Am 07.07.2014 17:58, schrieb Xavier Morel:
On 2014-07-07, at 13:22 , Andreas Maier
wrote:
While discussing Python issue #12067
(http://bugs.python.org/issue12067#msg222442), I learned that Python
3.4 implements '==' and '!=' on the object type such that if no
special equality test operations are implemented in derived classes,
there is a default implementation that tests for identity (as opposed
to equality of the values).
[...]
IMHO, that default implementation contradicts the definition that
'==' and '!=' test for equality of the values of an object.
[...]
To me, a sensible default implementation for == on object would be
(in Python):
if v is w:
return True;
elif type(v) != type(w):
return False
else:
raise ValueError("Equality cannot be determined in default
implementation")
Why would comparing two objects of different types return False
Because I think (but I'm not sure) that the type should play a role
for comparison of values. But maybe that does not embrace duck typing
sufficiently, and the type should be ignored by default for comparing
object values.
but comparing two objects of the same type raise an error?
That I'm sure of: Because the default implementation (after having
exhausted all possibilities of calling __eq__ and friends) has no way
to find out whether the values(!!) of the objects are equal.
IMHO, in Python context, "value" is a very vague term. Quite often we
can read it as the very basic (but not the only one) notion of "what
makes objects being equal or not" -- and then saying that "objects are
compared by value" is a tautology.
In other words, what object's "value" is -- is dependent on its nature:
e.g. the value of a list is what are the values of its consecutive
(indexed) items; the value of a set is based on values of all its
elements without notion of order or repetition; the value of a number is
a set of its abstract mathematical properties that determine what makes
objects being equal, greater, lesser, how particular arithmetic
operations work etc...
I think, there is no universal notion of "the value of a Python
object". The notion of identity seems to be most generic (every object
has it, event if it does not have any other property) -- and that's why
by default it is used to define the most basic feature of object's
*value*, i.e. "what makes objects being equal or not" (== and !=).
Another possibility would be to raise TypeError but, as Ethan Furman
wrote, it would be impractical (e.g. key-type-heterogenic dicts or sets
would be practically impossible to work with). On the other hand, the
notion of sorting order (< > <= >=) is a much more specialized object
property.
Cheers.
*j
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] == on object tests identity in 3.x
On 07/07/2014 22:11, Jan Kaliszewski wrote: [snip] IMHO, in Python context, "value" is a very vague term. Quite often we can read it as the very basic (but not the only one) notion of "what makes objects being equal or not" -- and then saying that "objects are compared by value" is a tautology. In other words, what object's "value" is -- is dependent on its nature: e.g. the value of a list is what are the values of its consecutive (indexed) items; the value of a set is based on values of all its elements without notion of order or repetition; the value of a number is a set of its abstract mathematical properties that determine what makes objects being equal, greater, lesser, how particular arithmetic operations work etc... I think, there is no universal notion of "the value of a Python object". The notion of identity seems to be most generic (every object has it, event if it does not have any other property) -- and that's why by default it is used to define the most basic feature of object's *value*, i.e. "what makes objects being equal or not" (== and !=). Another possibility would be to raise TypeError but, as Ethan Furman wrote, it would be impractical (e.g. key-type-heterogenic dicts or sets would be practically impossible to work with). On the other hand, the notion of sorting order (< > <= >=) is a much more specialized object property. Quite so. x, y = object(), object() print 'Equal:', ' '.join(attr for attr in dir(x) if getattr(x,attr)==getattr(y,attr)) print 'Unequal:', ' '.join(attr for attr in dir(x) if getattr(x,attr)!=getattr(y,attr)) Equal: __class__ __doc__ __new__ __subclasshook__ Unequal: __delattr__ __format__ __getattribute__ __hash__ __init__ __reduce__ __reduce_ex__ __repr__ __setattr__ __sizeof__ __str__ Andreas, what attribute or combination of attributes do you think should be the "values" of x and y? Rob Cliffe ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Tracker Stats
On Mon, Jul 7, 2014 at 10:01 PM, francis wrote:
> On 06/23/2014 10:12 PM, R. David Murray wrote:
>
>> The stats graphs are based on the data generated for the
>> weekly issue report. I have a patched version of that
>> report that adds the bug/enhancement info. I'll try to dig
>> it up this week; someone ping me if I forget :) It think
>> the patch will need to be updated based on Ezio's changes.
>>
> ping
>
If you just want some numbers you can try this:
>>> import xmlrpclib
>>> x = xmlrpclib.ServerProxy('http://bugs.python.org/xmlrpc', allow_none=True)
>>> open_issues = x.filter('issue', None, dict(status=1)) # 1 == open
>>> len(open_issues)
4541
>>> len(x.filter('issue', open_issues, dict(type=5))) # behavior
1798
>>> len(x.filter('issue', open_issues, dict(type=6))) # enhancement
1557
>>> len(x.filter('issue', open_issues, dict(type=1))) # crash
122
>>> len(x.filter('issue', open_issues, dict(type=2))) # compile error
141
>>> len(x.filter('issue', open_issues, dict(type=3))) # resource usage
103
>>> len(x.filter('issue', open_issues, dict(type=4))) # security
32
>>> len(x.filter('issue', open_issues, dict(type=7))) # performance
83
Best Regards,
Ezio Melotti
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] == on object tests identity in 3.x
Am 2014-07-07 19:43, schrieb Ethan Furman: On 07/07/2014 09:56 AM, Andreas Maier wrote: Am 07.07.2014 17:55, schrieb Ethan Furman: On 07/07/2014 04:22 AM, Andreas Maier wrote: Where is the discrepancy between the documentation of == and its default implementation on object documented? There's seems to be no discrepancy (at least, you have not shown it), The documentation states consistently that == tests the equality of the value of an object. The default implementation of == in both 2.x and 3.x tests the object identity. Is that not a discrepancy? One could say that the value of an object is the object itself. Since different objects are different, then they are not equal. but to answer the question about why the default equals operation is an identity test: - all objects should be equal to themselves (there is only one that isn't, and it's weird) I agree. But that is not a reason to conclude that different objects (as per their identity) should be unequal. Which is what the default implementation does. Python cannot know which values are important in an equality test, and which are not. So it refuses to guess. Well, one could argue that using the address of an object for its value equality test is pretty close to guessing, considering that given a sensible definition of value equality, objects of different identity can very well be equal but will always be considered unequal based on the address. Think of a chess board, for example. Are any two black pawns equal? All 16 pawns came from the same Pawn class, the only differences would be in the color and position, but the movement type is the same for all. So equality for a pawn might mean the same color, or it might mean color and position, or it might mean can move to the same position... it's up to the programmer to decide which of the possibilities is the correct one. Quite frankly, have equality mean identity in this case also makes a lot of sense. That's why I think equality is only defined once the class designer has defined it. Using the address as a default for equality (that is, in absence of such a designer's definition) may be an easy-to-implement default, but not a very logical or sensible one. - equality tests should not, as a general rule, raise exceptions -- they should return True or False Why not? Ordering tests also raise exceptions if ordering is not implemented. Besides the pawn example, this is probably a matter of practicality over purity -- equality tests are used extensively through-out Python, and having exceptions raised at possibly any moment would not be a fun nor productive environment. So we have many cases of classes whose designers thought about whether a sensible definition of equality was needed, and decided that an address/identity-based equality definition was just what they needed, yet they did not want to or could not use the "is" operator? Can you give me an example for such a class (besides type object)? (I.e. a class that does not have __eq__() and __ne__() but whose instances are compared with == or !=) Ordering is much less frequent, and since we already tried always ordering things, falling back to type name if necessary, we have discovered that that is not a good trade-off. So now if one tries to order things without specifying how it should be done, one gets an exception. In Python 2, the default ordering implementation on type object uses the identity (address) as the basis for ordering. In Python 3, that was changed to raise an exception. That seems to be in sync with what you are saying. Maybe it would have been possible to also change that for the default equality implementation in Python 3. But it was not changed. As I wrote in another response, we now need to document this properly. ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] == on object tests identity in 3.x
Am 2014-07-07 23:11, schrieb Jan Kaliszewski:
07.07.2014 18:11, Andreas Maier wrote:
Am 07.07.2014 17:58, schrieb Xavier Morel:
On 2014-07-07, at 13:22 , Andreas Maier wrote:
While discussing Python issue #12067
(http://bugs.python.org/issue12067#msg222442), I learned that
Python 3.4 implements '==' and '!=' on the object type such that if
no special equality test operations are implemented in derived
classes, there is a default implementation that tests for identity
(as opposed to equality of the values).
[...]
IMHO, that default implementation contradicts the definition that
'==' and '!=' test for equality of the values of an object.
[...]
To me, a sensible default implementation for == on object would be
(in Python):
if v is w:
return True;
elif type(v) != type(w):
return False
else:
raise ValueError("Equality cannot be determined in default
implementation")
Why would comparing two objects of different types return False
Because I think (but I'm not sure) that the type should play a role
for comparison of values. But maybe that does not embrace duck typing
sufficiently, and the type should be ignored by default for comparing
object values.
but comparing two objects of the same type raise an error?
That I'm sure of: Because the default implementation (after having
exhausted all possibilities of calling __eq__ and friends) has no way
to find out whether the values(!!) of the objects are equal.
IMHO, in Python context, "value" is a very vague term. Quite often we
can read it as the very basic (but not the only one) notion of "what
makes objects being equal or not" -- and then saying that "objects are
compared by value" is a tautology.
In other words, what object's "value" is -- is dependent on its
nature: e.g. the value of a list is what are the values of its
consecutive (indexed) items; the value of a set is based on values of
all its elements without notion of order or repetition; the value of a
number is a set of its abstract mathematical properties that determine
what makes objects being equal, greater, lesser, how particular
arithmetic operations work etc...
I think, there is no universal notion of "the value of a Python
object". The notion of identity seems to be most generic (every
object has it, event if it does not have any other property) -- and
that's why by default it is used to define the most basic feature of
object's *value*, i.e. "what makes objects being equal or not" (== and
!=). Another possibility would be to raise TypeError but, as Ethan
Furman wrote, it would be impractical (e.g. key-type-heterogenic dicts
or sets would be practically impossible to work with). On the other
hand, the notion of sorting order (< > <= >=) is a much more
specialized object property.
On the universal notion of a value in Python: In both 2.x and 3.x, it
reads (in 3.1. Objects, values and types):
- "Every object has an identity, a type and a value."
- "An object's /identity/ never changes once it has been created;
The /value/ of some objects can change. Objects whose value can change
are said to be /mutable/; objects whose value is unchangeable once they
are created are called /immutable/."
These are clear indications that there is an intention to have separate
concepts of identity and value in Python. If an instance of type object
can exist but does not have a universal notion of value, it should not
allow operations that need a value.
I do not really buy into the arguments that try to show how identity and
value are somehow the same. They are not, not even in Python.
The argument I can absolutely buy into is that the implementation cannot
be changed within a major release. So the real question is how we
document it.
I'll try to summarize in a separate posting.
Andy
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] == on object tests identity in 3.x
Am 2014-07-07 23:31, schrieb Rob Cliffe: On 07/07/2014 22:11, Jan Kaliszewski wrote: [snip] IMHO, in Python context, "value" is a very vague term. Quite often we can read it as the very basic (but not the only one) notion of "what makes objects being equal or not" -- and then saying that "objects are compared by value" is a tautology. In other words, what object's "value" is -- is dependent on its nature: e.g. the value of a list is what are the values of its consecutive (indexed) items; the value of a set is based on values of all its elements without notion of order or repetition; the value of a number is a set of its abstract mathematical properties that determine what makes objects being equal, greater, lesser, how particular arithmetic operations work etc... I think, there is no universal notion of "the value of a Python object". The notion of identity seems to be most generic (every object has it, event if it does not have any other property) -- and that's why by default it is used to define the most basic feature of object's *value*, i.e. "what makes objects being equal or not" (== and !=). Another possibility would be to raise TypeError but, as Ethan Furman wrote, it would be impractical (e.g. key-type-heterogenic dicts or sets would be practically impossible to work with). On the other hand, the notion of sorting order (< > <= >=) is a much more specialized object property. Quite so. x, y = object(), object() print 'Equal:', ' '.join(attr for attr in dir(x) if getattr(x,attr)==getattr(y,attr)) print 'Unequal:', ' '.join(attr for attr in dir(x) if getattr(x,attr)!=getattr(y,attr)) Equal: __class__ __doc__ __new__ __subclasshook__ Unequal: __delattr__ __format__ __getattribute__ __hash__ __init__ __reduce__ __reduce_ex__ __repr__ __setattr__ __sizeof__ __str__ Andreas, what attribute or combination of attributes do you think should be the "values" of x and y? Rob Cliffe Whatever the object's type defines to be the value. Which requires the presence of an __eq__() or __ne__() implementation. I could even live with a default implementation on type object that ANDs the equality of all instance data attributes and class data attributes, but that is not possible because type object does not have a notion of such data attributes. Reverting to using the identity for the value of an instance of type object is somehow helpless. It may make existing code work, but it is not very logical. I could even argue it makes some logical code fail, because while it reliably detects that the same objects are equal, it fails to detect that different objects may also be equal (at least under a sensible definition of value equality). Having said all this: As a few people already wrote, we cannot change the implementation within a major release. So the real question is how we document it. I'll try to summarize in a separate posting. Andy ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] == on object tests identity in 3.x
On Mon, Jul 7, 2014, at 16:36, Andreas Maier wrote: > Am 2014-07-07 19:43, schrieb Ethan Furman: > > On 07/07/2014 09:56 AM, Andreas Maier wrote: > >> Am 07.07.2014 17:55, schrieb Ethan Furman: > >>> On 07/07/2014 04:22 AM, Andreas Maier wrote: > > Where is the discrepancy between the documentation of == and its > default implementation on object documented? > >>> > >>> There's seems to be no discrepancy (at least, you have not shown it), > >> > >> The documentation states consistently that == tests the equality of > >> the value of an object. The default implementation > >> of == in both 2.x and 3.x tests the object identity. Is that not a > >> discrepancy? > > > > One could say that the value of an object is the object itself. Since > > different objects are different, then they are not equal. > > > >>> but to answer the question about why the default equals operation is an > >>> identity test: > >>> > >>>- all objects should be equal to themselves (there is only one that > >>> isn't, and it's weird) > >> > >> I agree. But that is not a reason to conclude that different objects > >> (as per their identity) should be unequal. Which is > >> what the default implementation does. > > > > Python cannot know which values are important in an equality test, and > > which are not. So it refuses to guess. > > > Well, one could argue that using the address of an object for its value > equality test is pretty close to guessing, considering that given a > sensible definition of value equality, objects of different identity can > very well be equal but will always be considered unequal based on the > address. Probably the best argument for the behavior is that "x is y" should imply "x == y", which preludes raising an exception. No such invariant is desired for ordering, so default implementations of < and > are not provided in Python 3. ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] == on object tests identity in 3.x - summary
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 ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] == on object tests identity in 3.x
Am 2014-07-08 01:49, schrieb Benjamin Peterson: On Mon, Jul 7, 2014, at 16:36, Andreas Maier wrote: Am 2014-07-07 19:43, schrieb Ethan Furman: On 07/07/2014 09:56 AM, Andreas Maier wrote: Am 07.07.2014 17:55, schrieb Ethan Furman: On 07/07/2014 04:22 AM, Andreas Maier wrote: Where is the discrepancy between the documentation of == and its default implementation on object documented? There's seems to be no discrepancy (at least, you have not shown it), The documentation states consistently that == tests the equality of the value of an object. The default implementation of == in both 2.x and 3.x tests the object identity. Is that not a discrepancy? One could say that the value of an object is the object itself. Since different objects are different, then they are not equal. but to answer the question about why the default equals operation is an identity test: - all objects should be equal to themselves (there is only one that isn't, and it's weird) I agree. But that is not a reason to conclude that different objects (as per their identity) should be unequal. Which is what the default implementation does. Python cannot know which values are important in an equality test, and which are not. So it refuses to guess. Well, one could argue that using the address of an object for its value equality test is pretty close to guessing, considering that given a sensible definition of value equality, objects of different identity can very well be equal but will always be considered unequal based on the address. Probably the best argument for the behavior is that "x is y" should imply "x == y", which preludes raising an exception. No such invariant is desired for ordering, so default implementations of < and > are not provided in Python 3. I agree that "x is y" should imply "x == y". The problem of the default implementation is that "x is not y" implies "x != y" and that may or may not be true under a sensible definition of equality. ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] == on object tests identity in 3.x
Am 2014-07-07 18:09, schrieb Ethan Furman: Just because two instances from the same object have the same value does not mean they are equal. For a real-life example, look at twins: biologically identical, yet not equal. I think they *are* equal in Python if they have the same value, by definition, because somewhere the Python docs state that equality compares the object's values. The reality though is that value is more vague than equality test (as it was already pointed out in this thread): A class designer can directly implement what equality means to the class, but he or she cannot implement an accessor method for the value. The value plays a role only indirectly as part of equality and ordering tests. Andy ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] == on object tests identity in 3.x
On 07/07/2014 04:36 PM, Andreas Maier wrote: Am 2014-07-07 19:43, schrieb Ethan Furman: Python cannot know which values are important in an equality test, and which are not. So it refuses to guess. Well, one could argue that using the address of an object for its value equality test is pretty close to guessing, considering that given a sensible definition of value equality, objects of different identity can very well be equal but will always be considered unequal based on the address. And what would be this 'sensible definition'? So we have many cases of classes whose designers thought about whether a sensible definition of equality was needed, and decided that an address/identity-based equality definition was just what they needed, yet they did not want to or could not use the "is" operator? 1) The address of the object is irrelevant. While that is what CPython uses, it is not what every Python uses. 2) The 'is' operator is specialized, and should only rarely be needed. If equals is what you mean, use '=='. 3) If Python forced us to write our own __eq__ /for every single class/ what would happen? Well, I suspect quite a few would make their own 'object' to inherit from, and would have the fallback of __eq__ meaning object identity. Practicality beats purity. Can you give me an example for such a class (besides type object)? (I.e. a class that does not have __eq__() and __ne__() but whose instances are compared with == or !=) I never add __eq__ to my classes until I come upon a place where I need to check if two instances of those classes are 'equal', for whatever I need equal to mean in that case. Ordering is much less frequent, and since we already tried always ordering things, falling back to type name if necessary, we have discovered that that is not a good trade-off. So now if one tries to order things without specifying how it should be done, one gets an exception. In Python 2, the default ordering implementation on type object uses the identity (address) as the basis for ordering. In Python 3, that was changed to raise an exception. That seems to be in sync with what you are saying. Maybe it would have been possible to also change that for the default equality implementation in Python 3. But it was not changed. As I wrote in another response, we now need to document this properly. Doc patches are gratefully accepted. :) -- ~Ethan~ ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] == on object tests identity in 3.x
On 07/07/2014 04:49 PM, Benjamin Peterson wrote: Probably the best argument for the behavior is that "x is y" should imply "x == y", which preludes raising an exception. No such invariant is desired for ordering, so default implementations of < and > are not provided in Python 3. Nice. This bit should definitely make it into the doc patch if not already in the docs. -- ~Ethan~ ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] == on object tests identity in 3.x
On 07/07/2014 05:12 PM, Andreas Maier wrote: Am 2014-07-07 18:09, schrieb Ethan Furman: Just because two instances from the same object have the same value does not mean they are equal. For a real-life example, look at twins: biologically identical, yet not equal. I think they *are* equal in Python if they have the same value, by definition, because somewhere the Python docs state that equality compares the object's values. And is personality of no value, then? The reality though is that value is more vague than equality test (as it was already pointed out in this thread): A class designer can directly implement what equality means to the class, but he or she cannot implement an accessor method for the value. The value plays a role only indirectly as part of equality and ordering tests. Not sure what you mean by this. -- ~Ethan~ ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] == on object tests identity in 3.x
Andreas Maier writes: > The problem of the default implementation is that "x is not y" > implies "x != y" and that may or may not be true under a sensible > definition of equality. I noticed this a long time ago and just decided it was covered by "consenting adults". That is, if the "sensible definition" of x == y is such that it can be true simultaneously with x != y, it's the programmer's responsibility to notice that, and to provide an implementation. But there's no issue that lack of an explicit implementation of comparison causes a program to have ambiguous meaning. I also consider that for "every object has a value" to make sense as a description of Python, that value must be representable by an object. The obvious default representation for the value of any object is the object itself! Now, for this purpose you don't need a "canonical representation" of an object's value. In particular, equality comparisons need not explicitly construct a representative object. Some do, some don't, I would suppose. For example, in comparing an integer with a float, I would convert the integer to float and compare, but in comparing float and complex I would check the complex for x.im == 0.0, and if true, return the value of x.re == y. I'm not sure how you interpret "value" to find the behavior of Python (the default comparison) problematic. I suspect you'd have a hard time coming up with an interpretation consistent with Python's object orientation. That said, it's probably worth documenting, but I don't know how much of the above should be introduced into the documentation. Steve ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] == on object tests identity in 3.x
Am 2014-07-08 01:50, schrieb Ethan Furman: On 07/07/2014 04:36 PM, Andreas Maier wrote: Am 2014-07-07 19:43, schrieb Ethan Furman: Python cannot know which values are important in an equality test, and which are not. So it refuses to guess. Well, one could argue that using the address of an object for its value equality test is pretty close to guessing, considering that given a sensible definition of value equality, objects of different identity can very well be equal but will always be considered unequal based on the address. And what would be this 'sensible definition'? One that only a class designer can define. That's why I argued for raising an exception if that is not defined. But as I stated elsewhere in this thread: It is as it is, and we need to document it. So we have many cases of classes whose designers thought about whether a sensible definition of equality was needed, and decided that an address/identity-based equality definition was just what they needed, yet they did not want to or could not use the "is" operator? 1) The address of the object is irrelevant. While that is what CPython uses, it is not what every Python uses. 2) The 'is' operator is specialized, and should only rarely be needed. If equals is what you mean, use '=='. 3) If Python forced us to write our own __eq__ /for every single class/ what would happen? Well, I suspect quite a few would make their own 'object' to inherit from, and would have the fallback of __eq__ meaning object identity. Practicality beats purity. Can you give me an example for such a class (besides type object)? (I.e. a class that does not have __eq__() and __ne__() but whose instances are compared with == or !=) I never add __eq__ to my classes until I come upon a place where I need to check if two instances of those classes are 'equal', for whatever I need equal to mean in that case. With that strategy, you would not be hurt if the default implementation raised an exception in case the two objects are not identical. ;-) Ordering is much less frequent, and since we already tried always ordering things, falling back to type name if necessary, we have discovered that that is not a good trade-off. So now if one tries to order things without specifying how it should be done, one gets an exception. In Python 2, the default ordering implementation on type object uses the identity (address) as the basis for ordering. In Python 3, that was changed to raise an exception. That seems to be in sync with what you are saying. Maybe it would have been possible to also change that for the default equality implementation in Python 3. But it was not changed. As I wrote in another response, we now need to document this properly. Doc patches are gratefully accepted. :) Understood. I will be working on it. :-) Andy ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] == on object tests identity in 3.x
Am 2014-07-08 02:22, schrieb Ethan Furman: On 07/07/2014 05:12 PM, Andreas Maier wrote: Am 2014-07-07 18:09, schrieb Ethan Furman: Just because two instances from the same object have the same value does not mean they are equal. For a real-life example, look at twins: biologically identical, yet not equal. I think they *are* equal in Python if they have the same value, by definition, because somewhere the Python docs state that equality compares the object's values. And is personality of no value, then? I guess you are pulling my leg, Ethan ... ;-) But again, for a definition of equality between instances of a Python class representing twins, one has to decide what attributes of the twins are supposed to be part of that. If the designer of the class decides that just the biology atributes are part of equality, fine. If he or she decides that personality attributes are additionally part of equality, also fine. The reality though is that value is more vague than equality test (as it was already pointed out in this thread): A class designer can directly implement what equality means to the class, but he or she cannot implement an accessor method for the value. The value plays a role only indirectly as part of equality and ordering tests. Not sure what you mean by this. Equality has a precise implementation (and hence definition) in Python; value does not. So to argue that value and equality can be different, is moot in a way, because it is not clear in Python what the value of an object is. Andy ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] == on object tests identity in 3.x
Andreas Maier writes: > A class designer can directly implement what equality means to the > class, but he or she cannot implement an accessor method for the > value. Of course she can! What you mean to say, I think, is that Python does not insist on an accessor method for the value. Ie, there is no dunder method __value__ on instances of class object. ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] == on object tests identity in 3.x
On Mon, Jul 07, 2014 at 04:52:17PM -0700, Ethan Furman wrote: > On 07/07/2014 04:49 PM, Benjamin Peterson wrote: > > > >Probably the best argument for the behavior is that "x is y" should > >imply "x == y", which preludes raising an exception. No such invariant > >is desired for ordering, so default implementations of < and > are not > >provided in Python 3. > > Nice. This bit should definitely make it into the doc patch if not already > in the docs. However, saying this should not preclude classes where this is not the case, e.g. IEEE-754 NANs. I would not like this wording (which otherwise is very nice) to be used in the future to force reflexivity on object equality. https://en.wikipedia.org/wiki/Reflexive_relation To try to cut off arguments: - Yes, it is fine to have the default implementation of __eq__ assume reflexivity. - Yes, it is fine for standard library containers (lists, dicts, etc.) to assume reflexivity of their items. - I'm fully aware that some people think the non-reflexivity of NANs is logically nonsensical and a mistake. I do not agree with them. - I'm not looking to change anything here, the current behaviour is fine, I just want to ensure that an otherwise admirable doc change does not get interpreted in the future in a way that prevents classes from defining __eq__ to be non-reflexive. -- Steven ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] == on object tests identity in 3.x
On 08/07/2014 00:37, Andreas Maier wrote: [...] Am 2014-07-07 23:11, schrieb Jan Kaliszewski: IMHO, in Python context, "value" is a very vague term. Quite often we can read it as the very basic (but not the only one) notion of "what makes objects being equal or not" -- and then saying that "objects are compared by value" is a tautology. In other words, what object's "value" is -- is dependent on its nature: e.g. the value of a list is what are the values of its consecutive (indexed) items; the value of a set is based on values of all its elements without notion of order or repetition; the value of a number is a set of its abstract mathematical properties that determine what makes objects being equal, greater, lesser, how particular arithmetic operations work etc... I think, there is no universal notion of "the value of a Python object". The notion of identity seems to be most generic (every object has it, event if it does not have any other property) -- and that's why by default it is used to define the most basic feature of object's *value*, i.e. "what makes objects being equal or not" (== and !=). Another possibility would be to raise TypeError but, as Ethan Furman wrote, it would be impractical (e.g. key-type-heterogenic dicts or sets would be practically impossible to work with). On the other hand, the notion of sorting order (< > <= >=) is a much more specialized object property. +1. See below. On the universal notion of a value in Python: In both 2.x and 3.x, it reads (in 3.1. Objects, values and types): - "*Every object has an identity, a type and a value.*" Hm, is that *really* true? Every object has an identity and a type, sure. Every *variable* has a value, which is an object (an instance of some class). (I think? :-) ) But ISTM that the notion of the value of an *object* exists more in our minds than in Python. We say that number and string objects have a value because the concepts of number and string, including how to compare them, are intuitive for us, and these objects by design reflect our concepts with some degree of fidelity. Ditto for lists, dictionaries and sets which are only slightly less intuitive. If I came across an int object and had no concept of what an integer number was, how would I know what its "value" is supposed to be? If I'm given an int object, "i", say, and pretend I don't know what an integer is, I see that len(dir(i)) == 64# Python 2.7 (and there may be attributes that dir doesn't show). How can I know from this bewildering list of 64 attributes (say they were all written in Swahili) that I can obtain the "real" (pun not intended) "value" with i.real or possibly i.numerator or i.__str__() or maybe somewhere else? ISTM "value" is a convention between humans, not something intrinsic to a class definition. Or at best something that is implied by the implementation of the comparison (or other) operators in the class. And can the following *objects* (class instances) be said to have a (obvious) value? obj1 = object() def obj2(): pass obj3 = (x for x in range(3)) obj4 = xrange(4) And is there any sensible way of comparing two such similar objects, e.g. obj3 = (x for x in range(3)) obj3a = (x for x in range(3)) except by id? Well, possibly in some cases. You might define two functions as equal if their code objects are identical (I'm outside my competence here, so please no-one correct me if I've got the technical detail wrong). But I don't see how you can compare two generators (other than by id) except by calling them both destructively (possibly an infinite number of times, and hoping that neither has unpredictable behaviour, side effects, etc.). As has already been said (more or less) in this thread, if you want to be able to compare any two objects of the same type, and not by id, you probably end up with a circular definition of "value" as "that (function of an object's attributes) which is compared". Which is ultimately an implementation decision for each type, not anything intrinsic to the type. So it makes sense to consistently fall back on id when nothing else obvious suggests itself. - "An object's /identity/ never changes once it has been created; The /value/ of some objects can change. Objects whose value can change are said to be /mutable/; objects whose value is unchangeable once they are created are called /immutable/." ISTM it needs to be explicitly documented for each class what the "value" of an instance is intended to be. Oh, I'm being pedantic here, sure. But I wonder if enforcing it would lead to more clarity of thought (maybe even the realisation that some objects don't have a value?? :-) ). These are clear indications that there is an intention to have separate concepts of identity and value in Python. If an instance of type object can exist but does not have a universal notion of value, it should not allow op
Re: [Python-Dev] == on object tests identity in 3.x
On Tue, Jul 8, 2014 at 11:59 AM, Rob Cliffe wrote: > If I came across an int object and had no concept of what an integer number > was, how would I know what its "value" is supposed to be? The value of an integer is the number it represents. In CPython, it's entirely possible to have multiple integer objects (ie objects with unique identities) with the same value, although AIUI there are Pythons for which that's not the case. The value of a float, Fraction, Decimal, or complex is also the number it represents, so when you compare 1==1.0, the answer is that they have the same value. They can't possibly have the same identity (every object has a single type), but they have the same value. But what *is* that value? It's not something that can be independently recognized, because casting to a different type might change the value: >>> i = 2**53+1 >>> f = float(i) >>> i == f False >>> f == int(f) True Ergo the comparison of a float to an int cannot be done by casting the int to float, nor by casting the float to int; it has to be done by comparing the abstract numbers represented. Those are the objects' values. But what's the value of a sentinel object? _SENTINEL = object() def f(x, y=_SENTINEL): do_something_with(x) if y is not _SENTINEL: do_something_with(y) I'd say this is a reasonable argument for the default object value to be identity. ChrisA ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] == on object tests identity in 3.x - summary
On Tue, Jul 08, 2014 at 01:53:06AM +0200, Andreas Maier wrote: > 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. > 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. > 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. > 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: 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. > 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 ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] == on object tests identity in 3.x
On 07/07/2014 06:58 PM, Steven D'Aprano wrote: On Mon, Jul 07, 2014 at 04:52:17PM -0700, Ethan Furman wrote: On 07/07/2014 04:49 PM, Benjamin Peterson wrote: Probably the best argument for the behavior is that "x is y" should imply "x == y", which preludes raising an exception. No such invariant is desired for ordering, so default implementations of < and > are not provided in Python 3. Nice. This bit should definitely make it into the doc patch if not already in the docs. However, saying this should not preclude classes where this is not the case, e.g. IEEE-754 NANs. I would not like this wording (which otherwise is very nice) to be used in the future to force reflexivity on object equality. https://en.wikipedia.org/wiki/Reflexive_relation To try to cut off arguments: - Yes, it is fine to have the default implementation of __eq__ assume reflexivity. - Yes, it is fine for standard library containers (lists, dicts, etc.) to assume reflexivity of their items. - I'm fully aware that some people think the non-reflexivity of NANs is logically nonsensical and a mistake. I do not agree with them. - I'm not looking to change anything here, the current behaviour is fine, I just want to ensure that an otherwise admirable doc change does not get interpreted in the future in a way that prevents classes from defining __eq__ to be non-reflexive. +1 ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] == on object tests identity in 3.x
On 07/07/2014 06:18 PM, Andreas Maier wrote: Am 2014-07-08 01:50, schrieb Ethan Furman: I never add __eq__ to my classes until I come upon a place where I need to check if two instances of those classes are 'equal', for whatever I need equal to mean in that case. With that strategy, you would not be hurt if the default implementation raised an exception in case the two objects are not identical. ;-) Yes, I would. Not identical means not equal until I say otherwise. Raising an exception instead of returning False (for __eq__) would be horrible. -- ~Ethan~ ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] == on object tests identity in 3.x
On Tue, Jul 08, 2014 at 02:59:30AM +0100, Rob Cliffe wrote: > >- "*Every object has an identity, a type and a value.*" > > Hm, is that *really* true? Yes. It's pretty much true by definition: objects are *defined* to have an identity, type and value, even if that value is abstract rather than concrete. > Every object has an identity and a type, sure. > Every *variable* has a value, which is an object (an instance of some > class). (I think? :-) ) I don't think so. Variables can be undefined, which means they don't have a value: py> del x py> print x Traceback (most recent call last): File "", line 1, in NameError: name 'x' is not defined > But ISTM that the notion of the value of an *object* exists more in our > minds than in Python. Pretty much. How could it be otherwise? Human beings define the semantics of objects, that is, their value, not Python. [...] > If I came across an int object and had no concept of what an integer > number was, how would I know what its "value" is supposed to be? You couldn't, any more than you would know what the value of a Watzit object was if you knew nothing about Watzits. The value of an object is intimitely tied to its semantics, what the object represents and what it is intended to be used for. In general, we can say nothing about the value of an object until we've read the documentation for the object. But we can be confident that the object has *some* value, otherwise what would be the point of it? In some cases, that value might be nothing more than it's identity, but that's okay. I think the problem we're having here is that some people are looking for a concrete definition of what the value of an object is, but there isn't one. [...] > And can the following *objects* (class instances) be said to have a > (obvious) value? > obj1 = object() > def obj2(): pass > obj3 = (x for x in range(3)) > obj4 = xrange(4) The value as understood by a human reader, as opposed to the value as assumed by Python, is not necessarily the same. As far as Python is concerned, the value of all four objects is the object itself, i.e. its identity. (For avoidance of doubt, not its id(), which is just a number.) A human reader could infer more than Python: - the second object is a "do nothing" function; - the third object is a lazy sequence (0, 1, 2); - the fourth object is a lazy sequence (0, 1, 2, 3); but since the class designer didn't deem it important enough, or practical enough, to implement an __eq__ method that takes those things into account, *for the purposes of equality* (but perhaps not other purposes) we say that the value is just the object itself, its identity. > And is there any sensible way of comparing two such similar objects, e.g. > obj3 = (x for x in range(3)) > obj3a = (x for x in range(3)) > except by id? In principle, one might peer into the two generators and note that they perform exactly the same computations on exactly the same input, and therefore should be deemed to have the same value. But since that's hard, and "exactly the same" is not always well-defined, Python doesn't try to be too clever and just uses a simpler idea: the value is the object itself. > Well, possibly in some cases. You might define two functions as equal > if their code objects are identical (I'm outside my competence here, so > please no-one correct me if I've got the technical detail wrong). But I > don't see how you can compare two generators (other than by id) except > by calling them both destructively (possibly an infinite number of > times, and hoping that neither has unpredictable behaviour, side > effects, etc.). Generator objects have code objects as well. py> x = (a for a in (1, 2)) py> x.gi_code at 0xb7ee39f8, file "", line 1> > >- "An object's /identity/ never changes once it has been created; > >The /value/ of some objects can change. Objects whose value can change > >are said to be /mutable/; objects whose value is unchangeable once > >they are created are called /immutable/." > > ISTM it needs to be explicitly documented for each class what the > "value" of an instance is intended to be. Why? What value (pun intended) is there in adding an explicit statement of value to every single class? "The value of a str is the str's sequence of characters." "The value of a list is the list's sequence of items." "The value of an int is the int's numeric value." "The value of a float is the float's numeric value, or in the case of INFs and NANs, that they are an INF or NAN." "The value of a complex number is the ordered pair of its real and imaginary components." "The value of a re MatchObject is the MatchObject itself." I don't see any benefit to forcing all classes to explicitly document this sort of thing. It's nearly always redundant and unnecessary. -- Steven ___ Python-Dev mailing list [email protected] https://mail.pyt
Re: [Python-Dev] == on object tests identity in 3.x
On Tue, Jul 8, 2014 at 1:12 PM, Steven D'Aprano wrote: > Why? What value (pun intended) is there in adding an explicit statement > of value to every single class? > > "The value of a str is the str's sequence of characters." > "The value of a list is the list's sequence of items." > "The value of an int is the int's numeric value." > "The value of a float is the float's numeric value, or in the case of > INFs and NANs, that they are an INF or NAN." > "The value of a complex number is the ordered pair of its real and > imaginary components." > "The value of a re MatchObject is the MatchObject itself." > > I don't see any benefit to forcing all classes to explicitly document > this sort of thing. It's nearly always redundant and unnecessary. It's important where it's not obvious. For instance, two lists with the same items are equal, two tuples with the same items are equal, but a list and a tuple with the same items aren't. Doesn't mean it necessarily has to be documented, though. ChrisA ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] == on object tests identity in 3.x
Ethan Furman writes:
> And what would be this 'sensible definition' [of value equality]?
I think that's the wrong question. I suppose Andreas's point is that
when the programmer doesn't provide a definition, there is no such
thing as a "sensible definition" to default to. I disagree, but given
that as the point of discussion, asking what the definition is, is moot.
> 2) The 'is' operator is specialized, and should only rarely be
>needed.
Nitpick: Except that it's the preferred way to express identity with
singletons, AFAIK. ("if x is None: ...", not "if x == None: ...".)
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] == on object tests identity in 3.x
On 08/07/2014 04:12, Steven D'Aprano wrote: On Tue, Jul 08, 2014 at 02:59:30AM +0100, Rob Cliffe wrote: - "*Every object has an identity, a type and a value.*" Hm, is that *really* true? Yes. It's pretty much true by definition: objects are *defined* to have an identity, type and value, even if that value is abstract rather than concrete. Except that in your last paragraph you imply that an explicit *definition* of the value is normally not in the docs. Every object has an identity and a type, sure. Every *variable* has a value, which is an object (an instance of some class). (I think? :-) ) I don't think so. Variables can be undefined, which means they don't have a value: py> del x py> print x Traceback (most recent call last): File "", line 1, in NameError: name 'x' is not defined I was aware of that but I considered that a deleted variable no longer existed. Not that it's important. But ISTM that the notion of the value of an *object* exists more in our minds than in Python. Pretty much. How could it be otherwise? Human beings define the semantics of objects, that is, their value, not Python. [...] If I came across an int object and had no concept of what an integer number was, how would I know what its "value" is supposed to be? You couldn't, any more than you would know what the value of a Watzit object was if you knew nothing about Watzits. The value of an object is intimitely tied to its semantics, what the object represents and what it is intended to be used for. In general, we can say nothing about the value of an object until we've read the documentation for the object. But we can be confident that the object has *some* value, otherwise what would be the point of it? In some cases, that value might be nothing more than it's identity, but that's okay. I think the problem we're having here is that some people are looking for a concrete definition of what the value of an object is, but there isn't one. [...] And can the following *objects* (class instances) be said to have a (obvious) value? obj1 = object() def obj2(): pass obj3 = (x for x in range(3)) obj4 = xrange(4) The value as understood by a human reader, as opposed to the value as assumed by Python, is not necessarily the same. As far as Python is concerned, the value of all four objects is the object itself, i.e. its identity. Is this mentioned in the docs? I couldn't find it in a quick look through the 2.7.8 language reference. (For avoidance of doubt, not its id(), which is just a number.) A human reader could infer more than Python: - the second object is a "do nothing" function; - the third object is a lazy sequence (0, 1, 2); - the fourth object is a lazy sequence (0, 1, 2, 3); but since the class designer didn't deem it important enough, or practical enough, to implement an __eq__ method that takes those things into account, *for the purposes of equality* (but perhaps not other purposes) we say that the value is just the object itself, its identity. And is there any sensible way of comparing two such similar objects, e.g. obj3 = (x for x in range(3)) obj3a = (x for x in range(3)) except by id? In principle, one might peer into the two generators and note that they perform exactly the same computations on exactly the same input, and therefore should be deemed to have the same value. But since that's hard, and "exactly the same" is not always well-defined, Python doesn't try to be too clever and just uses a simpler idea: the value is the object itself. Sure, I wasn't suggesting it was a sensible thing to do (quite the opposite), just playing devil's advocate. Well, possibly in some cases. You might define two functions as equal if their code objects are identical (I'm outside my competence here, so please no-one correct me if I've got the technical detail wrong). But I don't see how you can compare two generators (other than by id) except by calling them both destructively (possibly an infinite number of times, and hoping that neither has unpredictable behaviour, side effects, etc.). Generator objects have code objects as well. py> x = (a for a in (1, 2)) py> x.gi_code at 0xb7ee39f8, file "", line 1> - "An object's /identity/ never changes once it has been created; The /value/ of some objects can change. Objects whose value can change are said to be /mutable/; objects whose value is unchangeable once they are created are called /immutable/." ISTM it needs to be explicitly documented for each class what the "value" of an instance is intended to be. Why? What value (pun intended) is there in adding an explicit statement of value to every single class? It troubles me a bit that "value" seems to be a fuzzy concept - it has an obvious meaning for some types (int, float, list etc.) but for callable objects you tell me that their value is the object itself, but I can't find it in the docs. (Is the same true for module objects?) Apart from any
Re: [Python-Dev] == on object tests identity in 3.x
On 07/07/2014 08:34 PM, Stephen J. Turnbull wrote:
Ethan Furman writes:
And what would be this 'sensible definition' [of value equality]?
I think that's the wrong question. I suppose Andreas's point is that
when the programmer doesn't provide a definition, there is no such
thing as a "sensible definition" to default to. I disagree, but given
that as the point of discussion, asking what the definition is, is moot.
He eventually made that point, but until he did I thought he meant that there was such a sensible default definition, he
just wasn't sharing what he thought it might be with us.
2) The 'is' operator is specialized, and should only rarely be
needed.
Nitpick: Except that it's the preferred way to express identity with
singletons, AFAIK. ("if x is None: ...", not "if x == None: ...".)
Not a nit at all, at least in my code -- the number of times I use '==' far outweighs the number of times I use 'is'.
Thus, 'is' is rare.
(Now, of course, I'll have to go measure that assertion and probably find out I
am wrong :/ ).
--
~Ethan~
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] buildbot.python.org down again?
On 7 Jul 2014 10:47, "Guido van Rossum" wrote: > > It would still be nice to know who "the appropriate persons" are. Too much of our infrastructure seems to be maintained by house elves or the ITA. I volunteered to be the board's liaison to the infrastructure team, and getting more visibility around what the infrastructure *is* and how it's monitored and supported is going to be part of that. That will serve a couple of key purposes: - making the points of escalation clearer if anything breaks or needs improvement (although "[email protected]" is a good default choice) - making the current "todo" list of the infrastructure team more visible (both to calibrate resolution time expectations and to provide potential contributors an idea of what's involved) Noah has already set up http://status.python.org/ to track service status, I can see about getting buildbot.python.org added to the list. Cheers, Nick. > > > On Sun, Jul 6, 2014 at 11:33 PM, Terry Reedy wrote: >> >> On 7/6/2014 7:54 PM, Ned Deily wrote: >>> >>> As of the moment, buildbot.python.org seems to be down again. >> >> >> Several hours later, back up. >> >> >> > Where is the best place to report problems like this? >> >> We should have, if not already, an automatic system to detect down servers and report (email) to appropriate persons. >> >> -- >> Terry Jan Reedy >> >> >> ___ >> Python-Dev mailing list >> [email protected] >> https://mail.python.org/mailman/listinfo/python-dev >> Unsubscribe: https://mail.python.org/mailman/options/python-dev/guido%40python.org > > > > > -- > --Guido van Rossum (python.org/~guido) > > ___ > Python-Dev mailing list > [email protected] > https://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: https://mail.python.org/mailman/options/python-dev/ncoghlan%40gmail.com > ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] == on object tests identity in 3.x - summary
On 7 Jul 2014 19:22, "Andreas Maier" wrote: > > 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. In Python 2, it orders by type, and only then by id (which happens to be the address in CPython). > > 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. 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). > It seems to me that only option 2 really works. Indeed, and that's the version already documented. Regards, Nick. > > > Comments and further options welcome. > > Andy > > ___ > Python-Dev mailing list > [email protected] > https://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: https://mail.python.org/mailman/options/python-dev/ncoghlan%40gmail.com ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
