From 605b1d214ebd27d6756a2be158115cfafec5cf5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Wed, 12 Aug 2026 17:57:01 +0200 Subject: [PATCH] Register cache instance after being fully initialized Otherwise an instance can be accessed by another thread via the registry when it is still being initialized. And it may crash on missing attribute. Closes #15007 (grafted from f1840545f4eb5ae5c870a2557a7c3a0314fedb16) --HG-- branch : 8.0 --- trytond/trytond/cache.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/trytond/trytond/cache.py b/trytond/trytond/cache.py index 2e71da0be0..b896690699 100644 --- a/trytond/trytond/cache.py +++ b/trytond/trytond/cache.py @@ -83,7 +83,15 @@ class _CacheLocal(local): self.portable_id = str(uuid4()) -class BaseCache(object): +class _CacheMeta(type): + def __call__(cls, *args, **kwargs): + inst = super().__call__(*args, **kwargs) + assert inst._name not in BaseCache._instances, inst._name + BaseCache._instances[inst._name] = inst + return inst + + +class BaseCache(metaclass=_CacheMeta): _instances = {} context_ignored_keys = { 'client', '_request', '_check_access', '_skip_warnings', @@ -112,8 +120,6 @@ class BaseCache(object): self.duration = dt.timedelta(**duration) else: self.duration = None - assert self._name not in self._instances, self._name - self._instances[self._name] = self @classmethod def stats(cls):