[Python-checkins] cpython (merge 3.2 -> default): Merge
raymond.hettinger
python-checkins at python.org
Sun Oct 16 09:01:28 CEST 2011
http://hg.python.org/cpython/rev/5f4a871759ea
changeset: 72944:5f4a871759ea
parent: 72941:c63087ac1f6c
parent: 72943:8365f82f8a13
user: Raymond Hettinger <python at rcn.com>
date: Sun Oct 16 00:00:51 2011 -0700
summary:
Merge
files:
Lib/functools.py | 34 ++++++++++++++-----------
Lib/test/test_functools.py | 16 ++++++++++++
2 files changed, 35 insertions(+), 15 deletions(-)
diff --git a/Lib/functools.py b/Lib/functools.py
--- a/Lib/functools.py
+++ b/Lib/functools.py
@@ -146,7 +146,7 @@
hits = misses = 0
kwd_mark = (object(),) # separates positional and keyword args
- lock = Lock() # needed because ordereddicts aren't threadsafe
+ lock = Lock() # needed because OrderedDict isn't threadsafe
if maxsize is None:
cache = dict() # simple cache without ordering or size limit
@@ -160,13 +160,15 @@
try:
result = cache[key]
hits += 1
+ return result
except KeyError:
- result = user_function(*args, **kwds)
- cache[key] = result
- misses += 1
+ pass
+ result = user_function(*args, **kwds)
+ cache[key] = result
+ misses += 1
return result
else:
- cache = OrderedDict() # ordered least recent to most recent
+ cache = OrderedDict() # ordered least recent to most recent
cache_popitem = cache.popitem
cache_renew = cache.move_to_end
@@ -176,18 +178,20 @@
key = args
if kwds:
key += kwd_mark + tuple(sorted(kwds.items()))
- try:
- with lock:
+ with lock:
+ try:
result = cache[key]
- cache_renew(key) # record recent use of this key
+ cache_renew(key) # record recent use of this key
hits += 1
- except KeyError:
- result = user_function(*args, **kwds)
- with lock:
- cache[key] = result # record recent use of this key
- misses += 1
- if len(cache) > maxsize:
- cache_popitem(0) # purge least recently used cache entry
+ return result
+ except KeyError:
+ pass
+ result = user_function(*args, **kwds)
+ with lock:
+ cache[key] = result # record recent use of this key
+ misses += 1
+ if len(cache) > maxsize:
+ cache_popitem(0) # purge least recently used cache entry
return result
def cache_info():
diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py
--- a/Lib/test/test_functools.py
+++ b/Lib/test/test_functools.py
@@ -718,6 +718,22 @@
self.assertEqual(fib.cache_info(),
functools._CacheInfo(hits=0, misses=0, maxsize=None, currsize=0))
+ def test_lru_with_exceptions(self):
+ # Verify that user_function exceptions get passed through without
+ # creating a hard-to-read chained exception.
+ # http://bugs.python.org/issue13177
+ for maxsize in (None, 100):
+ @functools.lru_cache(maxsize)
+ def func(i):
+ return 'abc'[i]
+ self.assertEqual(func(0), 'a')
+ with self.assertRaises(IndexError) as cm:
+ func(15)
+ self.assertIsNone(cm.exception.__context__)
+ # Verify that the previous exception did not result in a cached entry
+ with self.assertRaises(IndexError):
+ func(15)
+
def test_main(verbose=None):
test_classes = (
TestPartial,
--
Repository URL: http://hg.python.org/cpython
More information about the Python-checkins
mailing list