More puzzling behavior while subclassing datetime
Peter Otten
__peter__ at web.de
Thu Nov 16 03:34:11 EST 2006
insyte at 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
More information about the Python-list
mailing list