From: hbc Date: Mon, 9 Feb 2015 14:32:30 +0000 (+0800) Subject: Make ``ttl`` argument optional. X-Git-Tag: 1.0.0~10^2~1 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=fbeb6d37448e6e5e93f31c7a6fd93cac4531a13f;p=cached-property.git Make ``ttl`` argument optional. Resolved #4. --- diff --git a/cached_property.py b/cached_property.py index 904d88f..1706c65 100644 --- a/cached_property.py +++ b/cached_property.py @@ -17,15 +17,23 @@ class cached_property(object): Source: https://github.com/bottlepy/bottle/commit/fa7733e075da0d790d809aa3d2f53071897e6f76 """ # noqa - def __init__(self, ttl=300): - self.ttl = ttl - - def __call__(self, func, doc=None): + def __init__(self, ttl=None): + ttl_or_func = ttl + self.ttl = None + if callable(ttl_or_func): + self.prepare_func(ttl_or_func) + else: + self.ttl = ttl_or_func + + def prepare_func(self, func, doc=None): + '''Prepare to cache object method.''' self.func = func self.__doc__ = doc or func.__doc__ self.__name__ = func.__name__ self.__module__ = func.__module__ + def __call__(self, func, doc=None): + self.prepare_func(func, doc) return self def __get__(self, obj, cls): @@ -35,7 +43,7 @@ class cached_property(object): now = time() try: value, last_update = obj._cache[self.__name__] - if self.ttl > 0 and now - last_update > self.ttl: + if self.ttl and self.ttl > 0 and now - last_update > self.ttl: raise AttributeError except (KeyError, AttributeError): value = self.func(obj) diff --git a/tests/test_cached_property.py b/tests/test_cached_property.py index f8c6e2c..7ef773d 100755 --- a/tests/test_cached_property.py +++ b/tests/test_cached_property.py @@ -30,7 +30,7 @@ class TestCachedProperty(unittest.TestCase): self.total1 += 1 return self.total1 - @cached_property() + @cached_property def add_cached(self): self.total2 += 1 return self.total2 @@ -45,6 +45,10 @@ class TestCachedProperty(unittest.TestCase): self.assertEqual(c.add_cached, 1) self.assertEqual(c.add_cached, 1) + # Cannot expire the cache. + with freeze_time("9999-01-01"): + self.assertEqual(c.add_cached, 1) + # It's customary for descriptors to return themselves if accessed # though the class, rather than through an instance. self.assertTrue(isinstance(Check.add_cached, cached_property)) @@ -56,7 +60,7 @@ class TestCachedProperty(unittest.TestCase): def __init__(self): self.total = 0 - @cached_property() + @cached_property def add_cached(self): self.total += 1 return self.total @@ -79,7 +83,7 @@ class TestCachedProperty(unittest.TestCase): def __init__(self): self.total = None - @cached_property() + @cached_property def add_cached(self): return self.total @@ -102,7 +106,7 @@ class TestThreadingIssues(unittest.TestCase): self.total = 0 self.lock = Lock() - @cached_property() + @cached_property def add_cached(self): sleep(1) # Need to guard this since += isn't atomic. @@ -134,6 +138,7 @@ class TestThreadingIssues(unittest.TestCase): class TestCachedPropertyWithTTL(unittest.TestCase): + def test_ttl_expiry(self): class Check(object): diff --git a/tests/test_threaded_cached_property.py b/tests/test_threaded_cached_property.py index 8b157bd..8022104 100755 --- a/tests/test_threaded_cached_property.py +++ b/tests/test_threaded_cached_property.py @@ -29,7 +29,7 @@ class TestCachedProperty(unittest.TestCase): self.total1 += 1 return self.total1 - @threaded_cached_property() + @threaded_cached_property def add_cached(self): self.total2 += 1 return self.total2 @@ -51,7 +51,7 @@ class TestCachedProperty(unittest.TestCase): def __init__(self): self.total = 0 - @threaded_cached_property() + @threaded_cached_property def add_cached(self): self.total += 1 return self.total @@ -74,7 +74,7 @@ class TestCachedProperty(unittest.TestCase): def __init__(self): self.total = None - @threaded_cached_property() + @threaded_cached_property def add_cached(self): return self.total @@ -95,7 +95,7 @@ class TestThreadingIssues(unittest.TestCase): self.total = 0 self.lock = Lock() - @threaded_cached_property() + @threaded_cached_property def add_cached(self): sleep(1) # Need to guard this since += isn't atomic.