Skip to content

Commit ad70c3c

Browse files
miss-islingtonBHUVANSH855StanFromIreland
authored
[3.13] gh-154892: Fix PyLong_AsLong() error checks in _zoneinfo (GH-154901) (#155058)
(cherry picked from commit 7b4165b) Co-authored-by: Bhuvansh <bhuvanshkataria@gmail.com> Co-authored-by: Stan Ulbrych <stan@python.org>
1 parent 3d70247 commit ad70c3c

3 files changed

Lines changed: 18 additions & 3 deletions

File tree

Lib/test/test_zoneinfo/test_zoneinfo.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,18 @@ def test_unambiguous(self):
316316
self.assertEqual(dt.utcoffset(), offset.utcoffset, dt)
317317
self.assertEqual(dt.dst(), offset.dst, dt)
318318

319+
def test_datetime_subclass_negative_components(self):
320+
class MinusOneDateTime(datetime):
321+
hour = minute = second = -1
322+
323+
zi = self.zone_from_key("UTC")
324+
dt = MinusOneDateTime(2024, 1, 1, tzinfo=zi)
325+
326+
self.assertEqual(dt.utcoffset(), ZERO)
327+
self.assertEqual(dt.dst(), ZERO)
328+
self.assertEqual(dt.tzname(), "UTC")
329+
self.assertEqual(zi.fromutc(dt), datetime(2024, 1, 1, tzinfo=zi))
330+
319331
def test_folds_and_gaps(self):
320332
test_cases = []
321333
for key in self.zones():
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix a bug in the C accelerator for :mod:`zoneinfo` where
2+
:class:`datetime.datetime` subclasses returning ``-1`` for ``hour``,
3+
``minute``, or ``second`` could incorrectly raise a :exc:`SystemError`.

Modules/_zoneinfo.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2309,7 +2309,7 @@ get_local_timestamp(PyObject *dt, int64_t *local_ts)
23092309
}
23102310
hour = PyLong_AsLong(num);
23112311
Py_DECREF(num);
2312-
if (hour == -1) {
2312+
if (hour == -1 && PyErr_Occurred()) {
23132313
return -1;
23142314
}
23152315

@@ -2319,7 +2319,7 @@ get_local_timestamp(PyObject *dt, int64_t *local_ts)
23192319
}
23202320
minute = PyLong_AsLong(num);
23212321
Py_DECREF(num);
2322-
if (minute == -1) {
2322+
if (minute == -1 && PyErr_Occurred()) {
23232323
return -1;
23242324
}
23252325

@@ -2329,7 +2329,7 @@ get_local_timestamp(PyObject *dt, int64_t *local_ts)
23292329
}
23302330
second = PyLong_AsLong(num);
23312331
Py_DECREF(num);
2332-
if (second == -1) {
2332+
if (second == -1 && PyErr_Occurred()) {
23332333
return -1;
23342334
}
23352335
}

0 commit comments

Comments
 (0)