[issue4395] Document auto __ne__ generation; provide a use case for non-trivial __ne__

2008-11-24 Thread Michael K. Edwards

Michael K. Edwards <[EMAIL PROTECTED]> added the comment:

It would be really useful to explain, right in this section, why __ne__
is worth having.  Something along these lines (based on the logic from
Python 2.x -- modify as necessary):



The values most commonly returned by the rich comparison methods are
True, False, and NotImplemented (which tells the Python interpreter to
try a different comparison strategy).  However, it is quite legal and
often useful to return some other value, usually one which can be
coerced to True/False by bool().

For instance, if equality testing of instances of some class is
computationally expensive, that class's implementation of __eq__ may
return a "comparison object" whose __nonzero__ method calculates and
caches the actual boolean value.  Subsequent references to this same
comparison object may be returned for subsequent, logically equivalent
comparisons; the expensive comparison takes place only once, when the
object is first used in a boolean context.  This class's implementation
of __ne__ could return, not just "not (self == other)", but an object
whose __nonzero__ method returns "not (self == other)" -- potentially
delaying the expensive operation until its result is really tested for
boolean truth.

Python allows the programmer to define __ne__ separately from __eq__ for
this and similar reasons.  It is up to the programmer to ensure that
bool(self != other) == (not bool(self == other)), if this is a desired
property.  (One can even imagine situations in which it is appropriate
for neither (self == other) nor (self != other) to be true.  For
instance, a mathematical theorem prover might contain values a, b, c,
... that are formally unknown, and raise an exception when a==b is used
in a boolean context, but allow comparison of M = (a==b) against N =
(a!=b).)



Now that I write this, I see a use for magic __logical_or__,
__logical_and__, and __logical_not__ methods, so that one can postpone
or even avoid the evaluation of expensive/indeterminate comparisons. 
Consider the expression:
  ((a==b) and (c==d)) and ((a!=b) and (d==f))
If my class is designed such that a==b and a!=b cannot both be true,
then I can conclude that this expression is false without evaluating any
of the equality/inequality tests.

Is it too late to request these for Python 3.0?

--
nosy: +medwards
title: Document auto __ne__ generation -> Document auto __ne__ generation; 
provide a use case for non-trivial __ne__

___
Python tracker <[EMAIL PROTECTED]>
<http://bugs.python.org/issue4395>
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue4395] Document auto __ne__ generation; provide a use case for non-trivial __ne__

2009-06-21 Thread Michael K. Edwards

Michael K. Edwards  added the comment:

The implementation you are looking for is in object_richcompare, in
http://svn.python.org/projects/python/branches/py3k/Objects/typeobject.c
.  It would be most accurate to say something like:

The "object" base class, from which all user-defined classes
inherit, provides a single "rich comparison" method to which all of the
comparison operators (__eq__, __ne__, __lt__, __le__, __ge__, __gt__)
map.  This method returns a non-trivial value (i. e., something other
than NotImplemented) in only two cases:
  * When called as __eq__, if the two objects are identical, this method
returns True.  (If they are not identical, it returns NotImplemented so
that the other object's implementation of __eq__ gets a chance to return
True.)
  * When called as __ne__, it calls the equivalent of "self == other";
if this returns a non-trivial value X, then it returns !X (which is
always either True or False).

--

___
Python tracker 
<http://bugs.python.org/issue4395>
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue4395] Document auto __ne__ generation; provide a use case for non-trivial __ne__

2009-06-21 Thread Michael K. Edwards

Michael K. Edwards  added the comment:

It would also be useful to point out that there is a shortcut in the
interpreter itself (PyObject_RichCompareBool, in object.c) which checks
the equivalent of id(a) == id(b) and bypasses __eq__/__ne__ if so. 
Since not every call to __eq__ passes through this function, it's fairly
important that implementations of __eq__ return either True or
NotImplemented when id(a) == id(b).  Ditto for extension modules;
anything that installs its own tp_richcompare should handle object
identity and __ne__ in substantially the same way, so that subclass
authors can rely on the documented behavior when overriding __eq__.

--

___
Python tracker 
<http://bugs.python.org/issue4395>
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com