Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > More puzzling behavior while subclassing datetime

Reply
Thread Tools

More puzzling behavior while subclassing datetime

 
 
insyte@gmail.com
Guest
Posts: n/a
 
      11-16-2006
With assistance from Gabriel and Frederik (and a few old threads in
c.l.p.) I've been making headway on my specialized datetime class. Now
I'm puzzled by behavior I didn't expect while attempting to use some of
the alternate datetime constructors. Specifically, it appears if I
call GeneralizedTime.now() it calls the __new__ method of my class but
treats keyword arguments as if they were positional.

My class:

class GeneralizedTime(datetime):
def __new__(cls, time=None, *args, **kwargs):
print time, args, kwargs
if isinstance(time, str):
timeValues, tzOffset = cls.stringToTimeTuple(time)
return datetime.__new__(cls, tzinfo=GenericTZ(tzOffset),
**timeValues)
elif isinstance(time, datetime):
timeValues = time.timetuple()[:6]
tzOffset = time.utcoffset()
return datetime.__new__(cls, tzinfo=GenericTZ(tzOffset),
*timeValues)
elif time is None:
print "Still gotta figure out now to do this one..."
else:
raise Invalidtime(time)
@staticmethod
def stringToTimeTuple(timeString):
... regex that parses timeString ...

>>> GeneralizedTime.today()

2006 (11, 16, 0, 35, 18, 747275, None) {}
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "gentime.py", line 106, in __new__
raise InvalidTime(time)
gentime.InvalidTime: 2006

So it appears the time tuple is being passed to
GeneralizedTime.__new__, but the first value is being assigned to the
"time" argument.

Is this a side effect of how datetime is implemented? Or am I doing
something screwy?

Thanks!

-Ben

 
Reply With Quote
 
 
 
 
wittempj@hotmail.com
Guest
Posts: n/a
 
      11-16-2006

http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> With assistance from Gabriel and Frederik (and a few old threads in
> c.l.p.) I've been making headway on my specialized datetime class. Now
> I'm puzzled by behavior I didn't expect while attempting to use some of
> the alternate datetime constructors. Specifically, it appears if I
> call GeneralizedTime.now() it calls the __new__ method of my class but
> treats keyword arguments as if they were positional.
>
> My class:
>
> class GeneralizedTime(datetime):
> def __new__(cls, time=None, *args, **kwargs):

datetime.datetime() takes these arguments: year, month, day[, hour[,
minute[, second[, microsecond[, tzinfo]]]]]), see
http://docs.python.org/lib/datetime-datetime.html
> print time, args, kwargs
> if isinstance(time, str):
> timeValues, tzOffset = cls.stringToTimeTuple(time)
> return datetime.__new__(cls, tzinfo=GenericTZ(tzOffset),
> **timeValues)
> elif isinstance(time, datetime):
> timeValues = time.timetuple()[:6]

time.timetuple() does not exist, see
http://docs.python.org/lib/module-time.html, time is represented as a
tuple. checkout time.mktime() on how to convert to a tuple to a time
> tzOffset = time.utcoffset()
> return datetime.__new__(cls, tzinfo=GenericTZ(tzOffset),
> *timeValues)
> elif time is None:
> print "Still gotta figure out now to do this one..."
> else:
> raise Invalidtime(time)
> @staticmethod
> def stringToTimeTuple(timeString):
> ... regex that parses timeString ...
>
> >>> GeneralizedTime.today()

> 2006 (11, 16, 0, 35, 18, 747275, None) {}
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> File "gentime.py", line 106, in __new__
> raise InvalidTime(time)
> gentime.InvalidTime: 2006
>
> So it appears the time tuple is being passed to
> GeneralizedTime.__new__, but the first value is being assigned to the
> "time" argument.
>
> Is this a side effect of how datetime is implemented? Or am I doing
> something screwy?
>
> Thanks!
>
> -Ben


A very cutback part of your code gets the basics working:
from datetime import datetime
class Invalidtime(Exception):
pass

class GeneralizedTime(datetime):
def __new__(cls, *args, **kwargs):
if isinstance(args, tuple):
return datetime.__new__(cls, *args)
else:
raise Invalidtime(args)

t = GeneralizedTime.today()
print t.year
print t.month
print t.day
print t.hour
print t.minute
print t.second
print t.microsecond
print t.tzinfo

 
Reply With Quote
 
 
 
 
Peter Otten
Guest
Posts: n/a
 
      11-16-2006
(E-Mail Removed) wrote:

> With assistance from Gabriel and Frederik (and a few old threads in
> c.l.p.) I've been making headway on my specialized datetime class. Now
> I'm puzzled by behavior I didn't expect while attempting to use some of
> the alternate datetime constructors. Specifically, it appears if I
> call GeneralizedTime.now() it calls the __new__ method of my class but
> treats keyword arguments as if they were positional.
>
> My class:
>
> class GeneralizedTime(datetime):
> def __new__(cls, time=None, *args, **kwargs):
> print time, args, kwargs
> if isinstance(time, str):
> timeValues, tzOffset = cls.stringToTimeTuple(time)
> return datetime.__new__(cls, tzinfo=GenericTZ(tzOffset),
> **timeValues)
> elif isinstance(time, datetime):
> timeValues = time.timetuple()[:6]
> tzOffset = time.utcoffset()
> return datetime.__new__(cls, tzinfo=GenericTZ(tzOffset),
> *timeValues)
> elif time is None:
> print "Still gotta figure out now to do this one..."
> else:
> raise Invalidtime(time)
> @staticmethod
> def stringToTimeTuple(timeString):
> ... regex that parses timeString ...
>
>>>> GeneralizedTime.today()

> 2006 (11, 16, 0, 35, 18, 747275, None) {}
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> File "gentime.py", line 106, in __new__
> raise InvalidTime(time)
> gentime.InvalidTime: 2006
>
> So it appears the time tuple is being passed to
> GeneralizedTime.__new__, but the first value is being assigned to the
> "time" argument.
>
> Is this a side effect of how datetime is implemented?


Yes. Consider:

>>> def today(time=None, *args):

.... print "time = ", time, "args = ", args
....
>>> today(2006, 11, 16)

time = 2006 args = (11, 16)

To fix the issue you'll probably have to remove the time=None parameter from
GeneralizedTime.__new__() and instead extract it from args or kwargs.

Peter

 
Reply With Quote
 
insyte@gmail.com
Guest
Posts: n/a
 
      11-16-2006
> Yes. Consider:
>
> >>> def today(time=None, *args):

> ... print "time = ", time, "args = ", args
> ...
> >>> today(2006, 11, 16)

> time = 2006 args = (11, 16)
>
> To fix the issue you'll probably have to remove the time=None parameter from
> GeneralizedTime.__new__() and instead extract it from args or kwargs.


D'oh. That *should* have been obvious.

I am now no longer allowed to program after midnight.

Thanks!

-Ben

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: [2.4.4] creating a datetime.datetime from an XML xs:dateTime skip@pobox.com Python 2 01-06-2009 01:31 PM
[2.4.4] creating a datetime.datetime from an XML xs:dateTime Martin Python 0 12-27-2008 08:08 PM
mx.DateTime to datetime.datetime mp Python 1 07-28-2006 10:57 PM
datetime: .datetime-.datetime = .timedelta, .time-.time=TypeError ? Christos TZOTZIOY Georgiou Python 3 09-13-2003 10:44 AM
RE: datetime: .datetime-.datetime = .timedelta, .time-.time=TypeError ? Tim Peters Python 0 09-09-2003 12:57 AM



Advertisments