[Python-Dev] PEP 410 (Decimal timestamp): the implementation is ready for a review (original) (raw)
Victor Stinner victor.stinner at gmail.com
Tue Feb 14 13:55:23 CET 2012
- Previous message: [Python-Dev] PEP 410 (Decimal timestamp): the implementation is ready for a review
- Next message: [Python-Dev] PEP 410 (Decimal timestamp): the implementation is ready for a review
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
A datetime module based approach would need to either use a mix of datetime.datetime() (when returning an absolute time) and datetime.timedelta() (when returning a time relative to an unknown starting point),
Returning a different type depending on the function would be surprising and confusing.
time.clock_gettime(CLOCK_REALTIME) would return datetime.datetime, whereas time.clock_gettime(CLOCK_MONOTONIC) would return datetime.timedelta?
Or time.clock_gettime(CLOCK_REALTIME) would return datetime.timedelta whereas time.time() would return datetime.datetime? What would be the logic?
or else just always return datetime.timedelta (even when we know the epoch and could theoretically make the time absolute).
datetime.timedelta is similar to decimal.Decimal, but I don't want to support both, one is enough. I prefer Decimal because it is simpler and "compatible" with float.
In the former case, it may be appropriate to adopt a boolean flag API design and the "I want high precision time" request marker would just be "datetime=True". You'd then get back either datetime.datetime() or datetime.timedelta() as appropriate for the specific API.
A boolean flag has a problem with the import of the decimal module: time.time(decimal=True) would need an implicit ("hidden") import of the decimal module.
Another argument present in the PEP: "The boolean argument API was rejected because it is not "pythonic". Changing the return type with a parameter value is preferred over a boolean parameter (a flag)." http://www.python.org/dev/peps/pep-0410/#add-a-boolean-argument
If handed a datetime value, you need to know the correct epoch value, do the subtraction, then extract the full precision timestamp from the resulting timedelta object.
datetime.datetime don't have a .totimestamp() method.
If I remember correctly, time.mktime(datetime.datetime.timetuple()) has issues with timezone and the DST.
- implement int and float on timedelta (where the latter is just "self.totalseconds()" and the former "int(self.totalseconds())")
It looks like an hack. Why would float(timedelta) return seconds? Why not minutes or nanoseconds? I prefer an unambiguously and explicit .toseconds() method.
The big problem is that datetime and timedelta pose a huge problem for compatibility with existing third party APIs that accept timestamp values.
I just think that datetime and timedelta are overkill and have more drawbacks than advantages. FYI when I implemented datetime, it just just implemented by calling datetime.datetime.fromtimestamp(). The user can do an explicit call to this function, and datetime.timedelta(seconds=ts) for timedelta.
This is in stark contrast to what happens with decimal.Decimal: coercion to float() or int() will potentially lose precision, but still basically works. While addition and subtraction of floats will fail, addition and subtraction of integers works fine. To avoid losing precision, it's sufficient to just avoid the coercion.
Why would you like to mix Decimal and float? If you ask explicitly to get Decimal timestamps, you should use Decimal everywhere or you lose advantages of this type (and may get TypeError).
I think the outline above really illustrates why the raw data type for timestamps should just be a number, not a higher level semantic type like timedelta or datetime. Eventually, you want to be able to express a timestamp as a number of seconds relative to a particular epoch. To do that, you want a number. Originally, we used ints, then, to support microsecond resolution, we used floats. The natural progression to support arbitrary resolutions is to decimal.Decimal.
Yep.
Then, the higher level APIs can be defined in terms of that high precision number. Would it be nice if there was a PyPI module that provided APIs that converted the raw timestamps in stat objects and other OS level APIs into datetime() and timedelta() objects as appropriate?
Do you really need a module to call datetime.datetime.fromtimestamp(ts) and datetime.timedelta(seconds=ts)?
timedelta.totalseconds() can be updated to accept a "timestamp" argument
Yes, it would be consistent with the other changes introduced by the PEP.
Also, by using decimal.Decimal, we open up the possibility of, at some point in the future, switching to returning high precision values by default
I don't think that it is necessary. Few people need this precision and float will always be faster than Decimal because float is implemented in hardware (FPU).
I read somewhere that IBM plans to implement decimal float in their CPU, but I suppose than it will also have a "small" size like 64 bits, whereas 64 bits is not enough for a nanosecond resolution (same issue than binary float).
implicit promotion of floats to decimal values in binary operations without losing data
I don't think that such change would be accepted. You should ask Stephan Krah or Mark Dickson :-)
--
I completed datetime, timedelta and boolean flag sections of the PEP 410.
Victor
- Previous message: [Python-Dev] PEP 410 (Decimal timestamp): the implementation is ready for a review
- Next message: [Python-Dev] PEP 410 (Decimal timestamp): the implementation is ready for a review
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]