ordering with duck typing in 3.1

A

andrew cooke

hi,

please, what am i doing wrong here? the docs say http://docs.python.org/release/3.1.3/library/stdtypes.html#comparisons "in general, __lt__() and __eq__() are sufficient, if you want the conventional meanings of the comparison operators" but i am seeing
assert 2 < three
E TypeError: unorderable types: int() < IntVar()

with this test:


class IntVar(object):

def __init__(self, value=None):
if value is not None: value = int(value)
self.value = value

def setter(self):
def wrapper(stream_in, thunk):
self.value = thunk()
return self.value
return wrapper

def __int__(self):
return self.value

def __lt__(self, other):
return self.value < other

def __eq__(self, other):
return self.value == other

def __hash__(self):
return hash(self.value)


class DynamicTest(TestCase):

def test_lt(self):
three = IntVar(3)
assert three < 4
assert 2 < three
assert 3 == three

so what am i missing?

thanks,
andrew
 
T

Thomas Rachel

Am 07.04.2012 14:23 schrieb andrew cooke:
class IntVar(object):

def __init__(self, value=None):
if value is not None: value = int(value)
self.value = value

def setter(self):
def wrapper(stream_in, thunk):
self.value = thunk()
return self.value
return wrapper

def __int__(self):
return self.value

def __lt__(self, other):
return self.value< other

def __eq__(self, other):
return self.value == other

def __hash__(self):
return hash(self.value)
so what am i missing?

If I don't confuse things, I think you are missing a __gt__() in your
IntVar() class.

This is because first, a '2 < three' is tried with 2.__lt__(three). As
this fails due to the used types, it is reversed: 'three > 2' is
equivalent. As your three doesn't have a __gt__(), three.__gt__(2) fails
as well.


Thomas
 
M

mwilson

Thomas said:
Am 07.04.2012 14:23 schrieb andrew cooke:



If I don't confuse things, I think you are missing a __gt__() in your
IntVar() class.

This is because first, a '2 < three' is tried with 2.__lt__(three). As
this fails due to the used types, it is reversed: 'three > 2' is
equivalent. As your three doesn't have a __gt__(), three.__gt__(2) fails
as well.

Practically, yes. Just that that's not what the documentation says. Looks
like Python no longer tries to cobble together missing relations based on
the "usual" properties of ordering.

Mel.
 
J

Jon Clements

Any reason you can't derive from int instead of object? You may also want to check out functions.total_ordering on 2.7+
 
N

Neil Cerutti

Any reason you can't derive from int instead of object? You may
also want to check out functions.total_ordering on 2.7+

functools.total_ordering

I was temporarily tripped up by the aforementioned documentation,
myself.
 
J

Jon Clements

functools.total_ordering

I was temporarily tripped up by the aforementioned documentation,
myself.

Oops. I sent it from a mobile tablet device - I got auto-corrected. But yes, it is functools.total_ordering - TY you Neil.

Jon.
 

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

Forum statistics

Threads
473,961
Messages
2,570,131
Members
46,689
Latest member
liammiller

Latest Threads

Top