Bug report
Bug description
Python/pytime.c converts a Python number of seconds to a PyTime_t
(a 64-bit nanosecond count). The two conversion paths report an overflow
with different messages:
- the integer path,
pytime_from_object(), calls pytime_overflow() →
"timestamp too large to convert to C PyTime_t";
- the float path,
pytime_from_double() (Python/pytime.c:639), calls
pytime_time_t_overflow() → "timestamp out of range for platform time_t".
But pytime_from_double() does not convert to time_t at all — it converts
to PyTime_t. The float path names the wrong type, and disagrees with the
integer path for the same conceptual overflow.
It is user-visible through any API that accepts a float number of seconds,
e.g. time.sleep():
>>> import time
>>> time.sleep(2.0 ** 63) # float path
OverflowError: timestamp out of range for platform time_t
>>> time.sleep(2 ** 63) # integer path
OverflowError: timestamp too large to convert to C PyTime_t
The message is also wrong in fact, not only in type: PyTime_t saturates at
roughly 292 years (int64 nanoseconds), whereas 64-bit time_t spans far
longer — so time.sleep(1e10) (~317 years) overflows PyTime_t while being
comfortably within time_t range. The reported time_t limit was never the
actual constraint.
Fix
pytime_from_double() should call pytime_overflow(), the same helper the
integer path already uses, so both report the PyTime_t overflow:
if (!((double)PyTime_MIN <= d && d < -(double)PyTime_MIN)) {
pytime_overflow();
*tp = 0;
return -1;
}
This is a one-line change; the correct helper already exists in the same file.
CPython versions
main (3.16). The float path has used pytime_time_t_overflow() since the
pytime_from_double() helper was introduced.
Linked PRs
Bug report
Bug description
Python/pytime.cconverts a Python number of seconds to aPyTime_t(a 64-bit nanosecond count). The two conversion paths report an overflow
with different messages:
pytime_from_object(), callspytime_overflow()→"timestamp too large to convert to C PyTime_t";pytime_from_double()(Python/pytime.c:639), callspytime_time_t_overflow()→"timestamp out of range for platform time_t".But
pytime_from_double()does not convert totime_tat all — it convertsto
PyTime_t. The float path names the wrong type, and disagrees with theinteger path for the same conceptual overflow.
It is user-visible through any API that accepts a float number of seconds,
e.g.
time.sleep():The message is also wrong in fact, not only in type:
PyTime_tsaturates atroughly 292 years (int64 nanoseconds), whereas 64-bit
time_tspans farlonger — so
time.sleep(1e10)(~317 years) overflowsPyTime_twhile beingcomfortably within
time_trange. The reportedtime_tlimit was never theactual constraint.
Fix
pytime_from_double()should callpytime_overflow(), the same helper theinteger path already uses, so both report the
PyTime_toverflow:This is a one-line change; the correct helper already exists in the same file.
CPython versions
main (3.16). The float path has used
pytime_time_t_overflow()since thepytime_from_double()helper was introduced.Linked PRs