Bug report
Bug description:
Modules/_zoneinfo.c:get_local_timestamp() incorrectly treats the valid integer value -1 returned by PyLong_AsLong() as an error for the hour, minute, and second fields.
PyLong_AsLong() returns -1 both on conversion failure and for the legitimate Python integer -1. The C API requires checking PyErr_Occurred() to distinguish these cases.
The function already does this correctly for toordinal():
ord = PyLong_AsLong(num);
if (ord == -1 && PyErr_Occurred()) {
return -1;
}
However, the checks for hour, minute, and second only test == -1:
hour = PyLong_AsLong(num);
if (hour == -1) {
return -1;
}
minute = PyLong_AsLong(num);
if (minute == -1) {
return -1;
}
second = PyLong_AsLong(num);
if (second == -1) {
return -1;
}
As a result, valid values of -1 are incorrectly treated as conversion failures, causing the function to return an error without an exception being set.
Reproducer
from datetime import datetime
from zoneinfo import ZoneInfo
class BadDateTime(datetime):
@property
def hour(self):
return -1
dt = BadDateTime(2024, 1, 1, tzinfo=ZoneInfo("UTC"))
dt.utcoffset()
Current behavior:
SystemError: <method 'utcoffset' of 'zoneinfo.ZoneInfo' objects> returned NULL without setting an exception
The same issue also affects:
ZoneInfo.dst()
ZoneInfo.tzname()
ZoneInfo.fromutc()
The issue reproduces on the current main branch on Linux.
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Linked PRs
Bug report
Bug description:
Modules/_zoneinfo.c:get_local_timestamp()incorrectly treats the valid integer value-1returned byPyLong_AsLong()as an error for thehour,minute, andsecondfields.PyLong_AsLong()returns-1both on conversion failure and for the legitimate Python integer-1. The C API requires checkingPyErr_Occurred()to distinguish these cases.The function already does this correctly for
toordinal():However, the checks for
hour,minute, andsecondonly test== -1:As a result, valid values of
-1are incorrectly treated as conversion failures, causing the function to return an error without an exception being set.Reproducer
Current behavior:
The same issue also affects:
ZoneInfo.dst()ZoneInfo.tzname()ZoneInfo.fromutc()The issue reproduces on the current
mainbranch on Linux.CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Linked PRs