__cmp__ between dissimilar objects

I

insyte

I have a class that has, as an attribute, an instance of
datetime.datetime(). I would like to be able to compare my class
directly to instances of datetime.datetime in addition to other
instances of my class. The value used for the comparison in either
case should be the value of the datetime attribute of the class:

from datetime import datetime

class GeneralizedTime(object):
def __init__(self, time=None):
if time is None:
self.datetime = datetime.now()
def __cmp__(self, x):
if isinstance(x, GeneralizedTime):
return cmp(self.datetime, x.datetime)
if isinstance(x, datetime):
return cmp(self.datetime, x)

Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: can't compare datetime.datetime to GeneralizedTime

Clearly I'm misunderstanding something, here. As I understand my code,
I'm directly comparing an instance of datetime (self.datetime) to
another instance of datetime.

What am I failing to grasp?

Thanks!

-Ben
 
G

Gabriel Genellina

At said:
I have a class that has, as an attribute, an instance of
datetime.datetime(). I would like to be able to compare my class
directly to instances of datetime.datetime in addition to other
instances of my class. The value used for the comparison in either
case should be the value of the datetime attribute of the class:

from datetime import datetime

class GeneralizedTime(object):
def __init__(self, time=None):
if time is None:
self.datetime = datetime.now()
def __cmp__(self, x):
if isinstance(x, GeneralizedTime):
return cmp(self.datetime, x.datetime)
if isinstance(x, datetime):
return cmp(self.datetime, x)


Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: can't compare datetime.datetime to GeneralizedTime

This appears to be some braindead code in the datetime class.
You have to provide all the "rich-comparison" methods, and even then,
will never work when a datetime instance is at the left of the comparison.

def __lt__(self, other): return self.__cmp__(other)<0
def __le__(self, other): return self.__cmp__(other)<=0
def __gt__(self, other): return self.__cmp__(other)>0
def __ge__(self, other): return self.__cmp__(other)>=0
def __eq__(self, other): return self.__cmp__(other)==0
def __ne__(self, other): return self.__cmp__(other)!=0

When the rich comparison methods raise NotImplementedError, the
comparison logic inside the interpreter tries reversing the operands.
But datetime objects don't do that, they raise TypeError, thus
preventing the operand reversing. So any comparison with datetime on
the left and your GeneralizedTime on the right side will fail.
If nobody has an explanation on *why* datetime does this, I'd say it's a bug.


--
Gabriel Genellina
Softlab SRL

__________________________________________________
Correo Yahoo!
Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
 
F

Fredrik Lundh

I have a class that has, as an attribute, an instance of
datetime.datetime(). I would like to be able to compare my class
directly to instances of datetime.datetime in addition to other
instances of my class. The value used for the comparison in either
case should be the value of the datetime attribute of the class:

from datetime import datetime

class GeneralizedTime(object):
def __init__(self, time=None):
if time is None:
self.datetime = datetime.now()
def __cmp__(self, x):
if isinstance(x, GeneralizedTime):
return cmp(self.datetime, x.datetime)
if isinstance(x, datetime):
return cmp(self.datetime, x)

Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: can't compare datetime.datetime to GeneralizedTime

Clearly I'm misunderstanding something, here. As I understand my code,
I'm directly comparing an instance of datetime (self.datetime) to
another instance of datetime.

sure looks like you're comparing a datetime instance against a GeneralizeTime
instance to me.

why not just inherit from datetime instead? or read footnote 4 under "supported
operations" on this page for info on how to implement mixed-type comparisions:

http://docs.python.org/lib/datetime-datetime.html

</F>
 
I

insyte

why not just inherit from datetime instead?

I'll probably do that in the next iteration.
or read footnote 4 under "supported operations" on this page for info on how to
implement mixed-type comparisions:

http://docs.python.org/lib/datetime-datetime.html

OK. I added a 'timetuple' attribute to my class. Now comparisons seem
to "just work". This has made it even more obvious to me that I don't
understand how comparisons function:

If the GeneralizedTime instance is on the LHS of the comparison and the
datetime instance on the RHS, why would datetime's __cmp__ method be
called? I assume its being called since GeneralizedTime sure doesn't
care whether or not it has a timetuple attribute...

I've read through the "Basic customization" section of the language
reference, which doesn't seem to describe a scenario where the __cmp__
method on the RHS is called.

Thanks...

-Ben
 
I

insyte

When the rich comparison methods raise NotImplementedError, the
comparison logic inside the interpreter tries reversing the operands.

Can you point me to a description of this algorithm? It doesn't seem
to be described in the documentation for the rich comparison or __cmp__
methods...

-Ben
 
G

Gabriel Genellina

sure looks like you're comparing a datetime instance against a GeneralizeTime
instance to me.

why not just inherit from datetime instead? or read footnote 4
under "supported
operations" on this page for info on how to implement mixed-type comparisions:

http://docs.python.org/lib/datetime-datetime.html

Ugh... I hope there were good reasons for doing things so convoluted...


--
Gabriel Genellina
Softlab SRL

__________________________________________________
Correo Yahoo!
Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
 
I

insyte

Can you point me to a description of this algorithm? It doesn't seem

So since I implemented __cmp__ instead of the rich comparison
operators, Python first tried to reverse the comparison. This gave
datetime the opportunity to throw TypeError *before* the interpreter
failed over to trying __cmp__.

Is that correct?

Thanks!

-Ben
 
G

Gabriel Genellina

At said:
So since I implemented __cmp__ instead of the rich comparison
operators, Python first tried to reverse the comparison. This gave
datetime the opportunity to throw TypeError *before* the interpreter
failed over to trying __cmp__.

Is that correct?

Exactly. And if datetime were not so special in its implementation, a
NotImplementedError (instead of TypeError) would have let your code a
chance of being executed.


--
Gabriel Genellina
Softlab SRL

__________________________________________________
Correo Yahoo!
Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
 

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,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top