]> granicus.if.org Git - python/commitdiff
merge
authorRaymond Hettinger <python@rcn.com>
Mon, 4 Mar 2013 07:58:40 +0000 (02:58 -0500)
committerRaymond Hettinger <python@rcn.com>
Mon, 4 Mar 2013 07:58:40 +0000 (02:58 -0500)
1  2 
Lib/test/test_functools.py

index fbf3ec4e02e4fa438dd540fdf6a63b8f9de1a556,db1e9348dd41310cfaf6544fa48378a7f7efb0fa..9b3c31ef33950c35dae0a8f97be86c02efad08c5
@@@ -779,45 -777,39 +779,70 @@@ class TestLRU(unittest.TestCase)
              self.assertEqual(square.cache_info().hits, 4)
              self.assertEqual(square.cache_info().misses, 4)
  
 +    def test_lru_with_keyword_args(self):
 +        @functools.lru_cache()
 +        def fib(n):
 +            if n < 2:
 +                return n
 +            return fib(n=n-1) + fib(n=n-2)
 +        self.assertEqual(
 +            [fib(n=number) for number in range(16)],
 +            [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]
 +        )
 +        self.assertEqual(fib.cache_info(),
 +            functools._CacheInfo(hits=28, misses=16, maxsize=128, currsize=16))
 +        fib.cache_clear()
 +        self.assertEqual(fib.cache_info(),
 +            functools._CacheInfo(hits=0, misses=0, maxsize=128, currsize=0))
 +
 +    def test_lru_with_keyword_args_maxsize_none(self):
 +        @functools.lru_cache(maxsize=None)
 +        def fib(n):
 +            if n < 2:
 +                return n
 +            return fib(n=n-1) + fib(n=n-2)
 +        self.assertEqual([fib(n=number) for number in range(16)],
 +            [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610])
 +        self.assertEqual(fib.cache_info(),
 +            functools._CacheInfo(hits=28, misses=16, maxsize=None, currsize=16))
 +        fib.cache_clear()
 +        self.assertEqual(fib.cache_info(),
 +            functools._CacheInfo(hits=0, misses=0, maxsize=None, currsize=0))
 +
+     def test_need_for_rlock(self):
+         # This will deadlock on an LRU cache that uses a regular lock
+         @functools.lru_cache(maxsize=10)
+         def test_func(x):
+             'Used to demonstrate a reentrant lru_cache call within a single thread'
+             return x
+         class DoubleEq:
+             'Demonstrate a reentrant lru_cache call within a single thread'
+             def __init__(self, x):
+                 self.x = x
+             def __hash__(self):
+                 return self.x
+             def __eq__(self, other):
+                 if self.x == 2:
+                     test_func(DoubleEq(1))
+                 return self.x == other.x
+         test_func(DoubleEq(1))                      # Load the cache
+         test_func(DoubleEq(2))                      # Load the cache
+         self.assertEqual(test_func(DoubleEq(2)),    # Trigger a re-entrant __eq__ call
+                          DoubleEq(2))               # Verify the correct return value
  def test_main(verbose=None):
      test_classes = (
 -        TestPartial,
 -        TestPartialSubclass,
 -        TestPythonPartial,
 +        TestPartialC,
 +        TestPartialPy,
 +        TestPartialCSubclass,
          TestUpdateWrapper,
          TestTotalOrdering,
 -        TestCmpToKey,
 +        TestCmpToKeyC,
 +        TestCmpToKeyPy,
          TestWraps,
          TestReduce,
          TestLRU,