From 0f56e90f0582a4171a9e3e1e2ffde2781be4bffd Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sat, 14 Aug 2010 23:52:08 +0000 Subject: [PATCH] Support cache sizes. --- Lib/functools.py | 2 +- Lib/test/test_functools.py | 48 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/Lib/functools.py b/Lib/functools.py index f6ae4f4a643..9f28004b52b 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -144,7 +144,7 @@ def lfu_cache(maxsize=100): wrapper.misses += 1 if len(cache) > maxsize: # purge the 10% least frequently used entries - for key, _ in nsmallest(maxsize // 10, + for key, _ in nsmallest(maxsize // 10 or 1, use_count.items(), key=itemgetter(1)): del cache[key], use_count[key] diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index 70a8ad62ec8..4dd6fabeea0 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -482,6 +482,30 @@ class TestLRU(unittest.TestCase): self.assertEqual(f.hits, 0) self.assertEqual(f.misses, 1) + # test size zero (which means "never-cache") + f_cnt = 0 + @functools.lru_cache(0) + def f(): + nonlocal f_cnt + f_cnt += 1 + return 20 + self.assertEqual(f(), 20) + self.assertEqual(f(), 20) + self.assertEqual(f(), 20) + self.assertEqual(f_cnt, 3) + + # test size one + f_cnt = 0 + @functools.lru_cache(1) + def f(): + nonlocal f_cnt + f_cnt += 1 + return 20 + self.assertEqual(f(), 20) + self.assertEqual(f(), 20) + self.assertEqual(f(), 20) + self.assertEqual(f_cnt, 1) + def test_lfu(self): def orig(x, y): return 3*x+y @@ -503,6 +527,30 @@ class TestLRU(unittest.TestCase): self.assertEqual(f.hits, 0) self.assertEqual(f.misses, 1) + # test size zero (which means "never-cache") + f_cnt = 0 + @functools.lfu_cache(0) + def f(): + nonlocal f_cnt + f_cnt += 1 + return 20 + self.assertEqual(f(), 20) + self.assertEqual(f(), 20) + self.assertEqual(f(), 20) + self.assertEqual(f_cnt, 3) + + # test size one + f_cnt = 0 + @functools.lfu_cache(1) + def f(): + nonlocal f_cnt + f_cnt += 1 + return 20 + self.assertEqual(f(), 20) + self.assertEqual(f(), 20) + self.assertEqual(f(), 20) + self.assertEqual(f_cnt, 1) + def test_main(verbose=None): test_classes = ( TestPartial,