Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Python (http://www.velocityreviews.com/forums/f43-python.html)
-   -   More puzzling behavior while subclassing datetime (http://www.velocityreviews.com/forums/t396398-more-puzzling-behavior-while-subclassing-datetime.html)

insyte@gmail.com 11-16-2006 06:38 AM

More puzzling behavior while subclassing datetime
 
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


wittempj@hotmail.com 11-16-2006 08:27 AM

Re: More puzzling behavior while subclassing datetime
 

insyte@gmail.com 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


Peter Otten 11-16-2006 08:34 AM

Re: More puzzling behavior while subclassing datetime
 
insyte@gmail.com 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


insyte@gmail.com 11-16-2006 10:52 AM

Re: More puzzling behavior while subclassing datetime
 
> 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



All times are GMT. The time now is 12:16 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.