Make ``ttl`` argument optional.
authorhbc <bcxxxxxx@gmail.com>
Mon, 9 Feb 2015 14:32:30 +0000 (22:32 +0800)
committerhbc <bcxxxxxx@gmail.com>
Mon, 9 Feb 2015 14:44:48 +0000 (22:44 +0800)
Resolved #4.

cached_property.py
tests/test_cached_property.py
tests/test_threaded_cached_property.py

index 904d88fc39a5308397b67f8f31df5f8d7756ea48..1706c65fcac7a26c36132e41df4716e17e3f0ce7 100644 (file)
@@ -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)
index f8c6e2c1c42d14420364ec994837907ad276316b..7ef773da12b7f10f6543b28ecf4455593c9f48ac 100755 (executable)
@@ -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):
index 8b157bdb013ff72e518a60c7c76e6c8a60653167..8022104b2f92150f7db1cc36039effe6a8563d99 100755 (executable)
@@ -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.