https://github.com/python/cpython/commit/450e9eaf735dc40faf536b337e6c784e2f9050e3
commit: 450e9eaf735dc40faf536b337e6c784e2f9050e3
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-03-18T15:20:45Z
summary:

[3.13] gh-146076: Fix crash when a `ZoneInfo` subclass is missing a 
`_weak_cache` (GH-146082) (GH-146115)

(cherry picked from commit 3b06d68d8a3cc1f37359af1d7ebb3d09e1222296)

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

files:
A Misc/NEWS.d/next/Library/2026-03-17-20-41-27.gh-issue-146076.yoBNnB.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 588244c8adc3fa..26fc500930f1a1 100644
--- a/Lib/test/test_zoneinfo/test_zoneinfo.py
+++ b/Lib/test/test_zoneinfo/test_zoneinfo.py
@@ -1595,6 +1595,18 @@ class ZI(self.klass):
             "Unexpected instance of int in ZI weak cache for key 
'America/Los_Angeles'"
         )
 
+    def test_deleted_weak_cache(self):
+        class ZI(self.klass):
+            pass
+        delattr(ZI, '_weak_cache')
+
+        # These should not segfault
+        with self.assertRaises(AttributeError):
+            ZI("UTC")
+
+        with self.assertRaises(AttributeError):
+            ZI.clear_cache()
+
     def test_inconsistent_weak_cache_setdefault(self):
         class Cache:
             def get(self, key, default=None):
diff --git 
a/Misc/NEWS.d/next/Library/2026-03-17-20-41-27.gh-issue-146076.yoBNnB.rst 
b/Misc/NEWS.d/next/Library/2026-03-17-20-41-27.gh-issue-146076.yoBNnB.rst
new file mode 100644
index 00000000000000..746f5b278829bd
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-03-17-20-41-27.gh-issue-146076.yoBNnB.rst
@@ -0,0 +1,2 @@
+:mod:`zoneinfo`: fix crashes when deleting ``_weak_cache`` from a
+:class:`zoneinfo.ZoneInfo` subclass.
diff --git a/Modules/_zoneinfo.c b/Modules/_zoneinfo.c
index a08c47e10d1e12..b590df4d5540ac 100644
--- a/Modules/_zoneinfo.c
+++ b/Modules/_zoneinfo.c
@@ -316,6 +316,9 @@ zoneinfo_ZoneInfo_impl(PyTypeObject *type, PyObject *key)
     }
 
     PyObject *weak_cache = get_weak_cache(state, type);
+    if (weak_cache == NULL) {
+        return NULL;
+    }
     instance = PyObject_CallMethod(weak_cache, "get", "O", key, Py_None);
     if (instance == NULL) {
         Py_DECREF(weak_cache);
@@ -499,6 +502,9 @@ zoneinfo_ZoneInfo_clear_cache_impl(PyTypeObject *type, 
PyTypeObject *cls,
 {
     zoneinfo_state *state = zoneinfo_get_state_by_cls(cls);
     PyObject *weak_cache = get_weak_cache(state, type);
+    if (weak_cache == NULL) {
+        return NULL;
+    }
 
     if (only_keys == NULL || only_keys == Py_None) {
         PyObject *rv = PyObject_CallMethod(weak_cache, "clear", NULL);

_______________________________________________
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]

Reply via email to