[3.15] gh-154892: Fix `PyLong_AsLong()` error checks in `_zoneinfo` (GH-154901) (#155056)

StanFromIreland <[email protected]> Sat, 01 Aug 2026 16:22:36 -0400 (EDT)
Newsgroups gmane.comp.python.cvs
Message-ID <[email protected]>
https://github.com/python/cpython/commit/74887c9b832ef316c83e3bff14de0c866e305c7b
commit: 74887c9b832ef316c83e3bff14de0c866e305c7b
branch: 3.15
author: Miss Islington (bot) <[email protected]>
committer: StanFromIreland <[email protected]>
date: 2026-08-01T20:22:23Z
summary:

[3.15] gh-154892: Fix `PyLong_AsLong()` error checks in `_zoneinfo` (GH-154901) (#155056)

(cherry picked from commit 7b4165b3b07638d8aeab79a880c52f2b51c56f37)

Co-authored-by: Bhuvansh <[email protected]>
Co-authored-by: Stan Ulbrych <[email protected]>

files:
A Misc/NEWS.d/next/Library/2026-07-29-21-37-39.gh-issue-154892.eQyJ3Z.rst
M Lib/test/test_zoneinfo/test_zoneinfo.py
M Modules/_zoneinfo.c

diff --git a/Lib/test/test_zoneinfo/test_zoneinfo.py b/Lib/test/test_zoneinfo/test_zoneinfo.py
index a10f434eb27590d..41ba92342ff2cbd 100644
--- a/Lib/test/test_zoneinfo/test_zoneinfo.py
+++ b/Lib/test/test_zoneinfo/test_zoneinfo.py
@@ -316,6 +316,18 @@ def test_unambiguous(self):
                 self.assertEqual(dt.utcoffset(), offset.utcoffset, dt)
                 self.assertEqual(dt.dst(), offset.dst, dt)
 
+    def test_datetime_subclass_negative_components(self):
+        class MinusOneDateTime(datetime):
+            hour = minute = second = -1
+
+        zi = self.zone_from_key("UTC")
+        dt = MinusOneDateTime(2024, 1, 1, tzinfo=zi)
+
+        self.assertEqual(dt.utcoffset(), ZERO)
+        self.assertEqual(dt.dst(), ZERO)
+        self.assertEqual(dt.tzname(), "UTC")
+        self.assertEqual(zi.fromutc(dt), datetime(2024, 1, 1, tzinfo=zi))
+
     def test_folds_and_gaps(self):
         test_cases = []
         for key in self.zones():
diff --git a/Misc/NEWS.d/next/Library/2026-07-29-21-37-39.gh-issue-154892.eQyJ3Z.rst b/Misc/NEWS.d/next/Library/2026-07-29-21-37-39.gh-issue-154892.eQyJ3Z.rst
new file mode 100644
index 000000000000000..5088b0418d26351
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-07-29-21-37-39.gh-issue-154892.eQyJ3Z.rst
@@ -0,0 +1,3 @@
+Fix a bug in the C accelerator for :mod:`zoneinfo` where
+:class:`datetime.datetime` subclasses returning ``-1`` for ``hour``,
+``minute``, or ``second`` could incorrectly raise a :exc:`SystemError`.
diff --git a/Modules/_zoneinfo.c b/Modules/_zoneinfo.c
index 2a7ac4498261e08..464e145438ae733 100644
--- a/Modules/_zoneinfo.c
+++ b/Modules/_zoneinfo.c
@@ -2311,7 +2311,7 @@ get_local_timestamp(PyObject *dt, int64_t *local_ts)
         }
         hour = PyLong_AsLong(num);
         Py_DECREF(num);
-        if (hour == -1) {
+        if (hour == -1 && PyErr_Occurred()) {
             return -1;
         }
 
@@ -2321,7 +2321,7 @@ get_local_timestamp(PyObject *dt, int64_t *local_ts)
         }
         minute = PyLong_AsLong(num);
         Py_DECREF(num);
-        if (minute == -1) {
+        if (minute == -1 && PyErr_Occurred()) {
             return -1;
         }
 
@@ -2331,7 +2331,7 @@ get_local_timestamp(PyObject *dt, int64_t *local_ts)
         }
         second = PyLong_AsLong(num);
         Py_DECREF(num);
-        if (second == -1) {
+        if (second == -1 && PyErr_Occurred()) {
             return -1;
         }
     }

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]