https://github.com/python/cpython/commit/6980b94c3a25a69278ef9b348fabec7831651e8e commit: 6980b94c3a25a69278ef9b348fabec7831651e8e branch: 3.14 author: Miss Islington (bot) <[email protected]> committer: serhiy-storchaka <[email protected]> date: 2026-03-18T15:23:46Z summary:
[3.14] gh-146076: Fix crash when a `ZoneInfo` subclass is missing a `_weak_cache` (GH-146082) (GH-146116) (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 8a58c7d68acf82..7201c16b3e8551 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 25f7eb7a44d827..976b653c77a9f5 100644 --- a/Modules/_zoneinfo.c +++ b/Modules/_zoneinfo.c @@ -321,6 +321,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); @@ -505,6 +508,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]
