From 923369f412fecd8b40ac5fe56453562e4418238c Mon Sep 17 00:00:00 2001 From: Omer Katz Date: Mon, 15 Mar 2021 17:02:44 +0200 Subject: Use a thread-safe implementation of cached_property. --- kombu/utils/objects.py | 66 ++++---------------------------------------- requirements/default.txt | 1 + t/unit/utils/test_objects.py | 51 ---------------------------------- 3 files changed, 6 insertions(+), 112 deletions(-) delete mode 100644 t/unit/utils/test_objects.py diff --git a/kombu/utils/objects.py b/kombu/utils/objects.py index 4f220439..04f2e1be 100644 --- a/kombu/utils/objects.py +++ b/kombu/utils/objects.py @@ -1,64 +1,8 @@ """Object Utilities.""" -class cached_property: - """Cached property descriptor. - - Caches the return value of the get method on first call. - - Examples: - .. code-block:: python - - @cached_property - def connection(self): - return Connection() - - @connection.setter # Prepares stored value - def connection(self, value): - if value is None: - raise TypeError('Connection must be a connection') - return value - - @connection.deleter - def connection(self, value): - # Additional action to do at del(self.attr) - if value is not None: - print('Connection {0!r} deleted'.format(value) - """ - - def __init__(self, fget=None, fset=None, fdel=None, doc=None): - self.__get = fget - self.__set = fset - self.__del = fdel - self.__doc__ = doc or fget.__doc__ - self.__name__ = fget.__name__ - self.__module__ = fget.__module__ - - def __get__(self, obj, type=None): - if obj is None: - return self - try: - return obj.__dict__[self.__name__] - except KeyError: - value = obj.__dict__[self.__name__] = self.__get(obj) - return value - - def __set__(self, obj, value): - if obj is None: - return self - if self.__set is not None: - value = self.__set(obj, value) - obj.__dict__[self.__name__] = value - - def __delete__(self, obj, _sentinel=object()): - if obj is None: - return self - value = obj.__dict__.pop(self.__name__, _sentinel) - if self.__del is not None and value is not _sentinel: - self.__del(obj, value) - - def setter(self, fset): - return self.__class__(self.__get, fset, self.__del) - - def deleter(self, fdel): - return self.__class__(self.__get, self.__set, fdel) +try: + from functools import cached_property +except ImportError: + # TODO: Remove this fallback once we drop support for Python < 3.8 + from cached_property import threaded_cached_property as cached_property diff --git a/requirements/default.txt b/requirements/default.txt index 79b0868d..fd2e8a61 100644 --- a/requirements/default.txt +++ b/requirements/default.txt @@ -1,3 +1,4 @@ importlib-metadata>=0.18; python_version<"3.8" +cached_property; python_version<"3.8" amqp>=5.0.5,<6.0.0 vine diff --git a/t/unit/utils/test_objects.py b/t/unit/utils/test_objects.py deleted file mode 100644 index a1ad2000..00000000 --- a/t/unit/utils/test_objects.py +++ /dev/null @@ -1,51 +0,0 @@ -from kombu.utils.objects import cached_property - - -class test_cached_property: - - def test_deleting(self): - - class X: - xx = False - - @cached_property - def foo(self): - return 42 - - @foo.deleter # noqa - def foo(self, value): - self.xx = value - - x = X() - del(x.foo) - assert not x.xx - x.__dict__['foo'] = 'here' - del(x.foo) - assert x.xx == 'here' - - def test_when_access_from_class(self): - - class X: - xx = None - - @cached_property - def foo(self): - return 42 - - @foo.setter # noqa - def foo(self, value): - self.xx = 10 - - desc = X.__dict__['foo'] - assert X.foo is desc - - assert desc.__get__(None) is desc - assert desc.__set__(None, 1) is desc - assert desc.__delete__(None) is desc - assert desc.setter(1) - - x = X() - x.foo = 30 - assert x.xx == 10 - - del(x.foo) -- cgit v1.2.1