[tryton-debian-vcs] cached-property branch upstream updated. upstream/1.0.0-1-g794062b

Mathias Behrle tryton-debian-vcs at alioth.debian.org
Sun Apr 26 21:26:25 UTC 2015


The following commit has been merged in the upstream branch:
https://alioth.debian.org/plugins/scmgit/cgi-bin/gitweb.cgi/?p=tryton/cached-property.git;a=commitdiff;h=upstream/1.0.0-1-g794062b

commit 794062b3a1b7b9463cdc3b20b36ac71bc0a51f28
Author: Mathias Behrle <mathiasb at m9s.biz>
Date:   Sun Apr 26 23:15:28 2015 +0200

    Adding upstream version 1.1.0.
    
    Signed-off-by: Mathias Behrle <mathiasb at m9s.biz>

diff --git a/HISTORY.rst b/HISTORY.rst
index 60bf2eb..ca6e3c2 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -3,11 +3,17 @@
 History
 -------
 
-1.0.0 (2014-02-13)
+1.1.0 (2015-04-04)
+++++++++++++++++++
+
+* Regression: As the cache was not always clearing, we've broken out the time to expire feature to it's own set of specific tools.
+* Fixed typo in README, thanks to @zoidbergwill.
+
+1.0.0 (2015-02-13)
 ++++++++++++++++++
 
 * Added timed to expire feature to ``cached_property`` decorator.
-* Changed ``del monopoly.boardwalk`` to ``del monopoly['boardwalk'] in order to support the new TTL feature.
+* **Backwards incompatiblity**: Changed ``del monopoly.boardwalk`` to ``del monopoly['boardwalk']`` in order to support the new TTL feature.
 
 0.1.5 (2014-05-20)
 ++++++++++++++++++
diff --git a/PKG-INFO b/PKG-INFO
index 986fb84..b420bf8 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: cached-property
-Version: 1.0.0
+Version: 1.1.0
 Summary: A cached-property for decorating methods in classes.
 Home-page: https://github.com/pydanny/cached-property
 Author: Daniel Greenfeld
@@ -12,7 +12,7 @@ Description: ===============================
         
         .. image:: https://badge.fury.io/py/cached-property.png
             :target: http://badge.fury.io/py/cached-property
-            
+        
         .. image:: https://travis-ci.org/pydanny/cached-property.png?branch=master
                 :target: https://travis-ci.org/pydanny/cached-property
         
@@ -61,7 +61,6 @@ Description: ===============================
         
         Let's convert the boardwalk property into a ``cached_property``.
         
-        
         .. code-block:: python
         
             from cached_property import cached_property
@@ -105,43 +104,12 @@ Description: ===============================
             >>> monopoly.boardwalk
             550
             >>> # invalidate the cache
-            >>> del monopoly['boardwalk']
+            >>> del monopoly.boardwalk
             >>> # request the boardwalk property again
             >>> monopoly.boardwalk
             600
             >>> monopoly.boardwalk
             600
-            
-        Timing out the cache
-        --------------------
-        
-        Sometimes you want the price of things to reset after a time. 
-        
-        .. code-block:: python
-            
-            import random
-            from cached_property import cached_property
-        
-            class Monopoly(object):
-        
-                @cached_property(ttl=5) # cache invalidates after 10 seconds
-                def dice(self):
-                    # I dare the reader to implement a game using this method of 'rolling dice'.
-                    return random.randint(2,12)
-        
-        .. code-block:: python
-        
-            >>> monopoly = Monopoly()
-            >>> monopoly.dice
-            10
-            >>> monopoly.dice
-            10
-            >>> from time import sleep
-            >>> sleep(6) # Sleeps long enough to expire the cache
-            >>> monopoly.dice
-            3
-            >>> monopoly.dice
-            3
         
         Working with Threads
         ---------------------
@@ -193,6 +161,47 @@ Description: ===============================
             >>> self.assertEqual(m.boardwalk, 550)
         
         
+        Timing out the cache
+        --------------------
+        
+        Sometimes you want the price of things to reset after a time. Use the ``ttl``
+        versions of ``cached_property`` and ``threaded_cached_property``.
+        
+        .. code-block:: python
+        
+            import random
+            from cached_property import cached_property_with_ttl
+        
+            class Monopoly(object):
+        
+                @cached_property_with_ttl(ttl=5) # cache invalidates after 5 seconds
+                def dice(self):
+                    # I dare the reader to implement a game using this method of 'rolling dice'.
+                    return random.randint(2,12)
+        
+        Now use it:
+        
+        .. code-block:: python
+        
+            >>> monopoly = Monopoly()
+            >>> monopoly.dice
+            10
+            >>> monopoly.dice
+            10
+            >>> from time import sleep
+            >>> sleep(6) # Sleeps long enough to expire the cache
+            >>> monopoly.dice
+            3
+            >>> monopoly.dice
+            3
+            >>> # This cache clearing does not always work, see note below.
+            >>> del monopoly['dice']
+            >>> monopoly.dice
+            6
+        
+        **Note:** The ``ttl`` tools do not reliably allow the clearing of the cache. This
+        is why they are broken out into seperate tools. See https://github.com/pydanny/cached-property/issues/16.
+        
         Credits
         --------
         
@@ -211,11 +220,17 @@ Description: ===============================
         History
         -------
         
-        1.0.0 (2014-02-13)
+        1.1.0 (2015-04-04)
+        ++++++++++++++++++
+        
+        * Regression: As the cache was not always clearing, we've broken out the time to expire feature to it's own set of specific tools.
+        * Fixed typo in README, thanks to @zoidbergwill.
+        
+        1.0.0 (2015-02-13)
         ++++++++++++++++++
         
         * Added timed to expire feature to ``cached_property`` decorator.
-        * Changed ``del monopoly.boardwalk`` to ``del monopoly['boardwalk'] in order to support the new TTL feature.
+        * **Backwards incompatiblity**: Changed ``del monopoly.boardwalk`` to ``del monopoly['boardwalk']`` in order to support the new TTL feature.
         
         0.1.5 (2014-05-20)
         ++++++++++++++++++
diff --git a/README.rst b/README.rst
index bbdb552..bdb9c51 100644
--- a/README.rst
+++ b/README.rst
@@ -4,7 +4,7 @@ cached-property
 
 .. image:: https://badge.fury.io/py/cached-property.png
     :target: http://badge.fury.io/py/cached-property
-    
+
 .. image:: https://travis-ci.org/pydanny/cached-property.png?branch=master
         :target: https://travis-ci.org/pydanny/cached-property
 
@@ -53,7 +53,6 @@ Now run it:
 
 Let's convert the boardwalk property into a ``cached_property``.
 
-
 .. code-block:: python
 
     from cached_property import cached_property
@@ -97,43 +96,12 @@ Results of cached functions can be invalidated by outside forces. Let's demonstr
     >>> monopoly.boardwalk
     550
     >>> # invalidate the cache
-    >>> del monopoly['boardwalk']
+    >>> del monopoly.boardwalk
     >>> # request the boardwalk property again
     >>> monopoly.boardwalk
     600
     >>> monopoly.boardwalk
     600
-    
-Timing out the cache
---------------------
-
-Sometimes you want the price of things to reset after a time. 
-
-.. code-block:: python
-    
-    import random
-    from cached_property import cached_property
-
-    class Monopoly(object):
-
-        @cached_property(ttl=5) # cache invalidates after 10 seconds
-        def dice(self):
-            # I dare the reader to implement a game using this method of 'rolling dice'.
-            return random.randint(2,12)
-
-.. code-block:: python
-
-    >>> monopoly = Monopoly()
-    >>> monopoly.dice
-    10
-    >>> monopoly.dice
-    10
-    >>> from time import sleep
-    >>> sleep(6) # Sleeps long enough to expire the cache
-    >>> monopoly.dice
-    3
-    >>> monopoly.dice
-    3
 
 Working with Threads
 ---------------------
@@ -185,6 +153,47 @@ Now use it:
     >>> self.assertEqual(m.boardwalk, 550)
 
 
+Timing out the cache
+--------------------
+
+Sometimes you want the price of things to reset after a time. Use the ``ttl``
+versions of ``cached_property`` and ``threaded_cached_property``.
+
+.. code-block:: python
+
+    import random
+    from cached_property import cached_property_with_ttl
+
+    class Monopoly(object):
+
+        @cached_property_with_ttl(ttl=5) # cache invalidates after 5 seconds
+        def dice(self):
+            # I dare the reader to implement a game using this method of 'rolling dice'.
+            return random.randint(2,12)
+
+Now use it:
+
+.. code-block:: python
+
+    >>> monopoly = Monopoly()
+    >>> monopoly.dice
+    10
+    >>> monopoly.dice
+    10
+    >>> from time import sleep
+    >>> sleep(6) # Sleeps long enough to expire the cache
+    >>> monopoly.dice
+    3
+    >>> monopoly.dice
+    3
+    >>> # This cache clearing does not always work, see note below.
+    >>> del monopoly['dice']
+    >>> monopoly.dice
+    6
+
+**Note:** The ``ttl`` tools do not reliably allow the clearing of the cache. This
+is why they are broken out into seperate tools. See https://github.com/pydanny/cached-property/issues/16.
+
 Credits
 --------
 
diff --git a/cached_property.egg-info/PKG-INFO b/cached_property.egg-info/PKG-INFO
index 986fb84..b420bf8 100644
--- a/cached_property.egg-info/PKG-INFO
+++ b/cached_property.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: cached-property
-Version: 1.0.0
+Version: 1.1.0
 Summary: A cached-property for decorating methods in classes.
 Home-page: https://github.com/pydanny/cached-property
 Author: Daniel Greenfeld
@@ -12,7 +12,7 @@ Description: ===============================
         
         .. image:: https://badge.fury.io/py/cached-property.png
             :target: http://badge.fury.io/py/cached-property
-            
+        
         .. image:: https://travis-ci.org/pydanny/cached-property.png?branch=master
                 :target: https://travis-ci.org/pydanny/cached-property
         
@@ -61,7 +61,6 @@ Description: ===============================
         
         Let's convert the boardwalk property into a ``cached_property``.
         
-        
         .. code-block:: python
         
             from cached_property import cached_property
@@ -105,43 +104,12 @@ Description: ===============================
             >>> monopoly.boardwalk
             550
             >>> # invalidate the cache
-            >>> del monopoly['boardwalk']
+            >>> del monopoly.boardwalk
             >>> # request the boardwalk property again
             >>> monopoly.boardwalk
             600
             >>> monopoly.boardwalk
             600
-            
-        Timing out the cache
-        --------------------
-        
-        Sometimes you want the price of things to reset after a time. 
-        
-        .. code-block:: python
-            
-            import random
-            from cached_property import cached_property
-        
-            class Monopoly(object):
-        
-                @cached_property(ttl=5) # cache invalidates after 10 seconds
-                def dice(self):
-                    # I dare the reader to implement a game using this method of 'rolling dice'.
-                    return random.randint(2,12)
-        
-        .. code-block:: python
-        
-            >>> monopoly = Monopoly()
-            >>> monopoly.dice
-            10
-            >>> monopoly.dice
-            10
-            >>> from time import sleep
-            >>> sleep(6) # Sleeps long enough to expire the cache
-            >>> monopoly.dice
-            3
-            >>> monopoly.dice
-            3
         
         Working with Threads
         ---------------------
@@ -193,6 +161,47 @@ Description: ===============================
             >>> self.assertEqual(m.boardwalk, 550)
         
         
+        Timing out the cache
+        --------------------
+        
+        Sometimes you want the price of things to reset after a time. Use the ``ttl``
+        versions of ``cached_property`` and ``threaded_cached_property``.
+        
+        .. code-block:: python
+        
+            import random
+            from cached_property import cached_property_with_ttl
+        
+            class Monopoly(object):
+        
+                @cached_property_with_ttl(ttl=5) # cache invalidates after 5 seconds
+                def dice(self):
+                    # I dare the reader to implement a game using this method of 'rolling dice'.
+                    return random.randint(2,12)
+        
+        Now use it:
+        
+        .. code-block:: python
+        
+            >>> monopoly = Monopoly()
+            >>> monopoly.dice
+            10
+            >>> monopoly.dice
+            10
+            >>> from time import sleep
+            >>> sleep(6) # Sleeps long enough to expire the cache
+            >>> monopoly.dice
+            3
+            >>> monopoly.dice
+            3
+            >>> # This cache clearing does not always work, see note below.
+            >>> del monopoly['dice']
+            >>> monopoly.dice
+            6
+        
+        **Note:** The ``ttl`` tools do not reliably allow the clearing of the cache. This
+        is why they are broken out into seperate tools. See https://github.com/pydanny/cached-property/issues/16.
+        
         Credits
         --------
         
@@ -211,11 +220,17 @@ Description: ===============================
         History
         -------
         
-        1.0.0 (2014-02-13)
+        1.1.0 (2015-04-04)
+        ++++++++++++++++++
+        
+        * Regression: As the cache was not always clearing, we've broken out the time to expire feature to it's own set of specific tools.
+        * Fixed typo in README, thanks to @zoidbergwill.
+        
+        1.0.0 (2015-02-13)
         ++++++++++++++++++
         
         * Added timed to expire feature to ``cached_property`` decorator.
-        * Changed ``del monopoly.boardwalk`` to ``del monopoly['boardwalk'] in order to support the new TTL feature.
+        * **Backwards incompatiblity**: Changed ``del monopoly.boardwalk`` to ``del monopoly['boardwalk']`` in order to support the new TTL feature.
         
         0.1.5 (2014-05-20)
         ++++++++++++++++++
diff --git a/cached_property.egg-info/SOURCES.txt b/cached_property.egg-info/SOURCES.txt
index ca7171f..3f9936d 100644
--- a/cached_property.egg-info/SOURCES.txt
+++ b/cached_property.egg-info/SOURCES.txt
@@ -14,4 +14,5 @@ cached_property.egg-info/not-zip-safe
 cached_property.egg-info/top_level.txt
 tests/__init__.py
 tests/test_cached_property.py
+tests/test_cached_property_ttl.py
 tests/test_threaded_cached_property.py
\ No newline at end of file
diff --git a/cached_property.py b/cached_property.py
index 85009ae..3547b43 100644
--- a/cached_property.py
+++ b/cached_property.py
@@ -2,7 +2,7 @@
 
 __author__ = 'Daniel Greenfeld'
 __email__ = 'pydanny at gmail.com'
-__version__ = '1.0.0'
+__version__ = '1.1.0'
 __license__ = 'BSD'
 
 from time import time
@@ -13,8 +13,44 @@ class cached_property(object):
     """ A property that is only computed once per instance and then replaces
         itself with an ordinary attribute. Deleting the attribute resets the
         property.
-
         Source: https://github.com/bottlepy/bottle/commit/fa7733e075da0d790d809aa3d2f53071897e6f76
+        """
+
+    def __init__(self, func):
+        self.__doc__ = getattr(func, '__doc__')
+        self.func = func
+
+    def __get__(self, obj, cls):
+        if obj is None:
+            return self
+        value = obj.__dict__[self.func.__name__] = self.func(obj)
+        return value
+
+
+class threaded_cached_property(cached_property):
+    """ A cached_property version for use in environments where multiple
+        threads might concurrently try to access the property.
+        """
+    def __init__(self, func):
+        super(threaded_cached_property, self).__init__(func)
+        self.lock = threading.RLock()
+
+    def __get__(self, obj, cls):
+        with self.lock:
+            # Double check if the value was computed before the lock was
+            # acquired.
+            prop_name = self.func.__name__
+            if prop_name in obj.__dict__:
+                return obj.__dict__[prop_name]
+
+            # If not, do the calculation and release the lock.
+            return super(threaded_cached_property, self).__get__(obj, cls)
+
+
+class cached_property_with_ttl(object):
+    """ A property that is only computed once per instance and then replaces
+        itself with an ordinary attribute. Setting the ttl to a number expresses
+        how long the property will last before being timed out.
         """  # noqa
 
     def __init__(self, ttl=None):
@@ -55,16 +91,17 @@ class cached_property(object):
 
         return value
 
-    def __delattr__(self, name):
-        print(name)
+# Aliases to make cached_property_with_ttl easier to use
+cached_property_ttl = cached_property_with_ttl
+timed_cached_property = cached_property_with_ttl
 
 
-class threaded_cached_property(cached_property):
+class threaded_cached_property_with_ttl(cached_property_with_ttl):
     """ A cached_property version for use in environments where multiple
         threads might concurrently try to access the property.
         """
     def __init__(self, ttl=None):
-        super(threaded_cached_property, self).__init__(ttl)
+        super(threaded_cached_property_with_ttl, self).__init__(ttl)
         self.lock = threading.RLock()
 
     def __get__(self, obj, cls):
@@ -76,4 +113,9 @@ class threaded_cached_property(cached_property):
                 return obj._cache[prop_name][0]
 
             # If not, do the calculation and release the lock.
-            return super(threaded_cached_property, self).__get__(obj, cls)
+            return super(threaded_cached_property_with_ttl, self).__get__(obj, cls)
+
+# Alias to make threaded_cached_property_with_ttl easier to use
+threaded_cached_property_ttl = threaded_cached_property_with_ttl
+timed_threaded_cached_property = threaded_cached_property_with_ttl
+
diff --git a/setup.py b/setup.py
index 0de70e8..2a6bca4 100755
--- a/setup.py
+++ b/setup.py
@@ -9,7 +9,7 @@ try:
 except ImportError:
     from distutils.core import setup
 
-__version__ = '1.0.0'
+__version__ = '1.1.0'
 
 readme = open('README.rst').read()
 history = open('HISTORY.rst').read().replace('.. :changelog:', '')
diff --git a/tests/test_cached_property.py b/tests/test_cached_property.py
index 7ef773d..d39778a 100755
--- a/tests/test_cached_property.py
+++ b/tests/test_cached_property.py
@@ -10,7 +10,6 @@ Tests for `cached-property` module.
 from time import sleep
 from threading import Lock, Thread
 import unittest
-from freezegun import freeze_time
 
 from cached_property import cached_property
 
@@ -45,10 +44,6 @@ 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))
@@ -72,7 +67,7 @@ class TestCachedProperty(unittest.TestCase):
         self.assertEqual(c.add_cached, 1)
 
         # Reset the cache.
-        del c._cache['add_cached']
+        del c.add_cached
         self.assertEqual(c.add_cached, 2)
         self.assertEqual(c.add_cached, 2)
 
@@ -98,7 +93,7 @@ class TestThreadingIssues(unittest.TestCase):
     def test_threads(self):
         """ How well does the standard cached_property implementation work with threads?
             Short answer: It doesn't! Use threaded_cached_property instead!
-        """  # noqa
+        """
 
         class Check(object):
 
@@ -135,29 +130,3 @@ class TestThreadingIssues(unittest.TestCase):
         # between 1 and num_threads, depending on thread scheduling and
         # preemption.
         self.assertEqual(c.add_cached, num_threads)
-
-
-class TestCachedPropertyWithTTL(unittest.TestCase):
-
-    def test_ttl_expiry(self):
-
-        class Check(object):
-
-            def __init__(self):
-                self.total = 0
-
-            @cached_property(ttl=100000)
-            def add_cached(self):
-                self.total += 1
-                return self.total
-
-        c = Check()
-
-        # Run standard cache assertion
-        self.assertEqual(c.add_cached, 1)
-        self.assertEqual(c.add_cached, 1)
-
-        # Expire the cache.
-        with freeze_time("9999-01-01"):
-            self.assertEqual(c.add_cached, 2)
-        self.assertEqual(c.add_cached, 2)
diff --git a/tests/test_cached_property.py b/tests/test_cached_property_ttl.py
old mode 100755
new mode 100644
similarity index 57%
copy from tests/test_cached_property.py
copy to tests/test_cached_property_ttl.py
index 7ef773d..78e2e27
--- a/tests/test_cached_property.py
+++ b/tests/test_cached_property_ttl.py
@@ -1,11 +1,20 @@
 # -*- coding: utf-8 -*-
 
 """
-tests.py
+test_threaded_cache_property.py
 ----------------------------------
 
-Tests for `cached-property` module.
+Tests for `cached-property` module, cached_property_with_ttl.
+Tests for `cached-property` module, threaded_cache_property_with_ttl.
 """
+import unittest
+from freezegun import freeze_time
+
+from cached_property import (
+    cached_property_with_ttl,
+    threaded_cached_property_with_ttl
+)
+
 
 from time import sleep
 from threading import Lock, Thread
@@ -30,7 +39,7 @@ class TestCachedProperty(unittest.TestCase):
                 self.total1 += 1
                 return self.total1
 
-            @cached_property
+            @cached_property_with_ttl
             def add_cached(self):
                 self.total2 += 1
                 return self.total2
@@ -51,7 +60,7 @@ class TestCachedProperty(unittest.TestCase):
 
         # 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))
+        self.assertTrue(isinstance(Check.add_cached, cached_property_with_ttl))
 
     def test_reset_cached_property(self):
 
@@ -60,7 +69,7 @@ class TestCachedProperty(unittest.TestCase):
             def __init__(self):
                 self.total = 0
 
-            @cached_property
+            @cached_property_with_ttl
             def add_cached(self):
                 self.total += 1
                 return self.total
@@ -83,7 +92,7 @@ class TestCachedProperty(unittest.TestCase):
             def __init__(self):
                 self.total = None
 
-            @cached_property
+            @cached_property_with_ttl
             def add_cached(self):
                 return self.total
 
@@ -106,7 +115,7 @@ class TestThreadingIssues(unittest.TestCase):
                 self.total = 0
                 self.lock = Lock()
 
-            @cached_property
+            @cached_property_with_ttl
             def add_cached(self):
                 sleep(1)
                 # Need to guard this since += isn't atomic.
@@ -146,7 +155,7 @@ class TestCachedPropertyWithTTL(unittest.TestCase):
             def __init__(self):
                 self.total = 0
 
-            @cached_property(ttl=100000)
+            @cached_property_with_ttl(ttl=100000)
             def add_cached(self):
                 self.total += 1
                 return self.total
@@ -161,3 +170,105 @@ class TestCachedPropertyWithTTL(unittest.TestCase):
         with freeze_time("9999-01-01"):
             self.assertEqual(c.add_cached, 2)
         self.assertEqual(c.add_cached, 2)
+
+
+class TestCachedProperty(unittest.TestCase):
+
+    def test_cached_property(self):
+
+        class Check(object):
+
+            def __init__(self):
+                self.total1 = 0
+                self.total2 = 0
+
+            @property
+            def add_control(self):
+                self.total1 += 1
+                return self.total1
+
+            @threaded_cached_property_with_ttl
+            def add_cached(self):
+                self.total2 += 1
+                return self.total2
+
+        c = Check()
+
+        # The control shows that we can continue to add 1.
+        self.assertEqual(c.add_control, 1)
+        self.assertEqual(c.add_control, 2)
+
+        # The cached version demonstrates how nothing new is added
+        self.assertEqual(c.add_cached, 1)
+        self.assertEqual(c.add_cached, 1)
+
+    def test_reset_cached_property(self):
+
+        class Check(object):
+
+            def __init__(self):
+                self.total = 0
+
+            @threaded_cached_property_with_ttl
+            def add_cached(self):
+                self.total += 1
+                return self.total
+
+        c = Check()
+
+        # Run standard cache assertion
+        self.assertEqual(c.add_cached, 1)
+        self.assertEqual(c.add_cached, 1)
+
+        # Reset the cache.
+        del c._cache['add_cached']
+        self.assertEqual(c.add_cached, 2)
+        self.assertEqual(c.add_cached, 2)
+
+    def test_none_cached_property(self):
+
+        class Check(object):
+
+            def __init__(self):
+                self.total = None
+
+            @threaded_cached_property_with_ttl
+            def add_cached(self):
+                return self.total
+
+        c = Check()
+
+        # Run standard cache assertion
+        self.assertEqual(c.add_cached, None)
+
+
+class TestThreadingIssues(unittest.TestCase):
+
+    def test_threads(self):
+        """ How well does this implementation work with threads?"""
+
+        class Check(object):
+
+            def __init__(self):
+                self.total = 0
+                self.lock = Lock()
+
+            @threaded_cached_property_with_ttl
+            def add_cached(self):
+                sleep(1)
+                # Need to guard this since += isn't atomic.
+                with self.lock:
+                    self.total += 1
+                return self.total
+
+        c = Check()
+        threads = []
+        for x in range(10):
+            thread = Thread(target=lambda: c.add_cached)
+            thread.start()
+            threads.append(thread)
+
+        for thread in threads:
+            thread.join()
+
+        self.assertEqual(c.add_cached, 1)
\ No newline at end of file
diff --git a/tests/test_threaded_cached_property.py b/tests/test_threaded_cached_property.py
index 8022104..0d87673 100755
--- a/tests/test_threaded_cached_property.py
+++ b/tests/test_threaded_cached_property.py
@@ -3,7 +3,6 @@
 """
 test_threaded_cache_property.py
 ----------------------------------
-
 Tests for `cached-property` module, threaded_cache_property.
 """
 
@@ -63,7 +62,7 @@ class TestCachedProperty(unittest.TestCase):
         self.assertEqual(c.add_cached, 1)
 
         # Reset the cache.
-        del c._cache['add_cached']
+        del c.add_cached
         self.assertEqual(c.add_cached, 2)
         self.assertEqual(c.add_cached, 2)
 
-- 
cached-property



More information about the tryton-debian-vcs mailing list