Perceived inconsistency in py3k documentation

G

Greg

Hello,

This is my first post here, so if this is not the correct place to ask
this, please direct me to the best place.

In looking at the py3k documentation for comparing two classes, two
different view points are expressed (at least it seems so to me).
1) At http://docs.python.org/py3k/reference/datamodel.html:
"There are no implied relationships among the comparison operators.
The truth of x==y does not imply that x!=y is false. Accordingly, when
defining __eq__(), one should also define __ne__()..."
-- This seems to support the view that if in our code, we would like
to use comparison operators <, >, =, !=, etc. then we should define a
__lt__(), __gt__(), __eq__(), __ne__(), etc. for each comparison
operator we would like.

This appears to contrast
2) At http://docs.python.org/py3k/library/stdtypes.html:
"Instances of a class cannot be ordered with respect to other
instances of the same class, or other types of object, unless the
class defines enough of the methods __lt__(), __le__(), __gt__(), and
__ge__() (in general, __lt__() and __eq__() are sufficient, if you
want the conventional meanings of the comparison operators)."
-- This seems to imply that to get all of the operators, only
__lt__() and __eq__() need to be defined (just __lt__() should suffice
though I thought).

So, which is it supposed to be? Or am I reading the documentation
wrong?

Thanks!
-Greg-
 
P

Peter Otten

Greg said:
This is my first post here, so if this is not the correct place to ask
this, please direct me to the best place.

This is a good place to get general advice and to discuss potential bugs
when you are unsure whether they actually are bugs.
If you are sure that you ran into a bug in python or want to suggest an
improvement of the documentation where it is wrong or unclear or hard to
understand you can report to http://bugs.python.org .
In looking at the py3k documentation for comparing two classes, two
different view points are expressed (at least it seems so to me).
1) At http://docs.python.org/py3k/reference/datamodel.html:
"There are no implied relationships among the comparison operators.
The truth of x==y does not imply that x!=y is false. Accordingly, when
defining __eq__(), one should also define __ne__()..."
-- This seems to support the view that if in our code, we would like
to use comparison operators <, >, =, !=, etc. then we should define a
__lt__(), __gt__(), __eq__(), __ne__(), etc. for each comparison
operator we would like.

This appears to contrast
2) At http://docs.python.org/py3k/library/stdtypes.html:
"Instances of a class cannot be ordered with respect to other
instances of the same class, or other types of object, unless the
class defines enough of the methods __lt__(), __le__(), __gt__(), and
__ge__() (in general, __lt__() and __eq__() are sufficient, if you
want the conventional meanings of the comparison operators)."
-- This seems to imply that to get all of the operators, only
__lt__() and __eq__() need to be defined (just __lt__() should suffice
though I thought).

So, which is it supposed to be? Or am I reading the documentation
wrong?

I agree with you that the documentation is at least unclear. The following
experiment suggests that list.sort() works correctly if only __lt__() and
__eq__() are implemented which in my reading is what your second quote
intends to convey. But "enough of the methods..." is a fuzzy statement.

The other finding:
(1) a != b is emulated with not (a == b)
(2) a > b is emulated with b < a
is not something I'd expect after reading your first quote, but technically
(2) is covered by

"""... __lt__() and __gt__() are each other’s reflection ..."""

$ cat py3compare.py
report = True

class A:
def __init__(self, key, side="A"):
self.key = key
self.side = side
def __eq__(self, other):
result = self.key == other.key
if report:
print(self, "__eq__", other, "-->", result)
return result
def __lt__(self, other):
result = self.key < other.key
if report:
print(self, "__lt__", other, "-->", result)
return result
def __str__(self):
return "{}({})".format(self.side, self.key)
def __repr__(self):
return str(self.key)

a = A(1, "L")
for k in range(3):
b = A(k, "R")
print("{} != {}: {}\n".format(a, b, a != b))
print("{} > {}: {}\n".format(a, b, a > b))
print()

import random
items = []
for n in 10, 20:
items.extend(map(A, range(n)))
random.shuffle(items)

report = False
items.sort()
print(items)

print(a <= b)
$ python3 py3compare.py
L(1) __eq__ R(0) --> False
L(1) != R(0): True

R(0) __lt__ L(1) --> True
L(1) > R(0): True


L(1) __eq__ R(1) --> True
L(1) != R(1): False

R(1) __lt__ L(1) --> False
L(1) > R(1): False


L(1) __eq__ R(2) --> False
L(1) != R(2): True

R(2) __lt__ L(1) --> False
L(1) > R(2): False


[0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19]
Traceback (most recent call last):
File "py3compare.py", line 39, in <module>
print(a <= b)
TypeError: unorderable types: A() <= A()
$

Conclusion: If you can come up with a text that is both correct and clear,
don't hesitate to tell us, here or on the bug tracker.

Peter

PS: The painless way out: always use @functools.total_ordering or the
equivalent cookbok recipe.
 
T

Terry Reedy

On 12/5/2010 3:31 AM, Greg wrote:

For future reference,

do not work because of the trailing :s, at least not with FireFox.

These, with space after the url, should. Other puctuation can be a
problem too, so it is best to always follow urls with whitespace.
 
A

Antoine Pitrou

On 12/5/2010 3:31 AM, Greg wrote:

For future reference,


do not work because of the trailing :s, at least not with FireFox.

Work fine here. The problem isn't Firefox, it is your e-mail or news
client.

Antoine.
 
S

Steve Holden

Work fine here. The problem isn't Firefox, it is your e-mail or news
client.

Antoine.
In my case also the links don't work, because my newsreader
(Thunderbird) makes the assumption that the colons are part of the URLs.
This behavior is common enough that people need to be aware of it.

regards
Steve
 
S

Steve Holden

Work fine here. The problem isn't Firefox, it is your e-mail or news
client.

Antoine.
In my case also the links don't work, because my newsreader
(Thunderbird) makes the assumption that the colons are part of the URLs.
This behavior is common enough that people need to be aware of it.

regards
Steve
 
S

Steven D'Aprano

In my case also the links don't work, because my newsreader
(Thunderbird) makes the assumption that the colons are part of the URLs.
This behavior is common enough that people need to be aware of it.

It seems to me that colons are legal inside URIs and don't need to be
escaped. If that is the case, then Thunderbird is correct to treat the
colon as part of the URL, and whatever client Antoine is using is wrong
to exclude it.

See this thread here for a discussion which concluded that colons are
legal and don't need to be escaped:

http://markmail.org/message/juowogoeiff44qc4


Personally, I never let any character except whitespace or < > delimiters
touch a URL. I never know how applications will interpret it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,955
Messages
2,570,117
Members
46,705
Latest member
v_darius

Latest Threads

Top