gh-146076: Fix crash when a ZoneInfo subclass is missing a _weak_cache (#146082)

This commit is contained in:
Stan Ulbrych 2026-03-18 12:58:08 +00:00 committed by GitHub
parent d42a04c045
commit 3b06d68d8a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 20 additions and 0 deletions

View file

@ -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):

View file

@ -0,0 +1,2 @@
:mod:`zoneinfo`: fix crashes when deleting ``_weak_cache`` from a
:class:`zoneinfo.ZoneInfo` subclass.

View file

@ -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);