mirror of
https://github.com/python/cpython.git
synced 2024-11-23 18:04:37 +08:00
Merge
This commit is contained in:
commit
d8886fc831
@ -146,7 +146,7 @@ def lru_cache(maxsize=100):
|
||||
|
||||
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 @@ def lru_cache(maxsize=100):
|
||||
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 @@ def lru_cache(maxsize=100):
|
||||
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():
|
||||
|
@ -718,6 +718,22 @@ class TestLRU(unittest.TestCase):
|
||||
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,
|
||||
|
Loading…
Reference in New Issue
Block a user