[issue2267] datetime.datetime operator methods are not subclass-friendly
Alexander Belopolsky
report at bugs.python.org
Wed Jun 9 20:51:08 CEST 2010
Alexander Belopolsky <belopolsky at users.sourceforge.net> added the comment:
I would like to take another shot at this. The link in Amaury's closing comment no longer works, so here is the relevant post:
"""
Returning same type as self for arithmetic in subclasses
Tim Peters tim.peters at gmail.com
Sat Jan 8 02:09:27 CET 2005
[Max M]
> """
> I subclass datetime and timedelta
>
> >>> dt = myDatetime(1970,1,1)
> >>> type(dt)
> <class 'dtime.myDatetime'>
>
> >>> td = myTimedelta(hours=1)
> >>> type(td)
> <class 'dtime.myTimedelta'>
>
> But when I do arithmetic with these classes, they return datetime and
> timedelta,
...
> >>> new_time = dt + td
> >>> new_time
> datetime.datetime(1970, 1, 1, 1, 0)
>
> >>> type(new_time)
> <type 'datetime.datetime'>
Yes, and all builtin Python types work that way. For example,
int.__add__ or float.__add__ applied to a subclass of int or float
will return an int or float; similarly for a subclass of str. This
was Guido's decision, based on that an implementation of any method in
a base class has no idea what requirements may exist for invoking a
subclass's constructor. For example, a subclass may restrict the
values of constructor arguments, or require more arguments than a base
class constructor; it may permute the order of positional arguments in
the base class constructor; it may even be "a feature" that a subclass
constructor gives a different meaning to an argument it shares with
the base class constructor. Since there isn't a way to guess, Python
does a safe thing instead.
> where I want them to return myDatetime and myTimedelta
>
> So I wondered if there was a simlpler way to coerce the result into my
> desired types rather than overwriting the __add__, __sub__ etc. methods?
Generally speaking, no. But I'm sure someone will torture you with a
framework that purports to make it easy <wink>.
""" http://mail.python.org/pipermail/python-list/2005-January/925838.html
As I explained in my previous post, the same argument, "base class has no idea what requirements may exist for invoking a subclass's constructor", applies to class methods, but they nevertheless consistently construct subclass instances:
>>> class d(datetime): pass
>>> d.utcfromtimestamp(0)
d(1970, 1, 1, 0, 0)
>>> d.fromtimestamp(0)
d(1969, 12, 31, 19, 0)
>>> d.combine(date(1,1,1), time(1,1))
d(1, 1, 1, 1, 1)
Similar example for the date class:
>>> class Date(date): pass
>>> Date.fromordinal(1)
Date(1, 1, 1)
In my view it is hard to justify that for a Date instance d, and integer days, Date.fromordinal(d.toordinal() + days) happily produces a Date instance, but d + timedelta(days) returns a basic date instance.
----------
assignee: -> belopolsky
components: +Extension Modules -Library (Lib)
nosy: +mark.dickinson
resolution: wont fix ->
status: closed -> open
versions: +Python 3.2 -Python 2.5
_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue2267>
_______________________________________
More information about the Python-bugs-list
mailing list