Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d8886fc

Browse files
committed
Merge
2 parents e606983 + 4b779b3 commit d8886fc

2 files changed

Lines changed: 35 additions & 15 deletions

File tree

Lib/functools.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ def decorating_function(user_function,
146146

147147
hits = misses = 0
148148
kwd_mark = (object(),) # separates positional and keyword args
149-
lock = Lock() # needed because ordereddicts aren't threadsafe
149+
lock = Lock() # needed because OrderedDict isn't threadsafe
150150

151151
if maxsize is None:
152152
cache = dict() # simple cache without ordering or size limit
@@ -160,13 +160,15 @@ def wrapper(*args, **kwds):
160160
try:
161161
result = cache[key]
162162
hits += 1
163+
return result
163164
except KeyError:
164-
result = user_function(*args, **kwds)
165-
cache[key] = result
166-
misses += 1
165+
pass
166+
result = user_function(*args, **kwds)
167+
cache[key] = result
168+
misses += 1
167169
return result
168170
else:
169-
cache = OrderedDict() # ordered least recent to most recent
171+
cache = OrderedDict() # ordered least recent to most recent
170172
cache_popitem = cache.popitem
171173
cache_renew = cache.move_to_end
172174

@@ -176,18 +178,20 @@ def wrapper(*args, **kwds):
176178
key = args
177179
if kwds:
178180
key += kwd_mark + tuple(sorted(kwds.items()))
179-
try:
180-
with lock:
181+
with lock:
182+
try:
181183
result = cache[key]
182-
cache_renew(key) # record recent use of this key
184+
cache_renew(key) # record recent use of this key
183185
hits += 1
184-
except KeyError:
185-
result = user_function(*args, **kwds)
186-
with lock:
187-
cache[key] = result # record recent use of this key
188-
misses += 1
189-
if len(cache) > maxsize:
190-
cache_popitem(0) # purge least recently used cache entry
186+
return result
187+
except KeyError:
188+
pass
189+
result = user_function(*args, **kwds)
190+
with lock:
191+
cache[key] = result # record recent use of this key
192+
misses += 1
193+
if len(cache) > maxsize:
194+
cache_popitem(0) # purge least recently used cache entry
191195
return result
192196

193197
def cache_info():

Lib/test/test_functools.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,22 @@ def fib(n):
718718
self.assertEqual(fib.cache_info(),
719719
functools._CacheInfo(hits=0, misses=0, maxsize=None, currsize=0))
720720

721+
def test_lru_with_exceptions(self):
722+
# Verify that user_function exceptions get passed through without
723+
# creating a hard-to-read chained exception.
724+
# http://bugs.python.org/issue13177
725+
for maxsize in (None, 100):
726+
@functools.lru_cache(maxsize)
727+
def func(i):
728+
return 'abc'[i]
729+
self.assertEqual(func(0), 'a')
730+
with self.assertRaises(IndexError) as cm:
731+
func(15)
732+
self.assertIsNone(cm.exception.__context__)
733+
# Verify that the previous exception did not result in a cached entry
734+
with self.assertRaises(IndexError):
735+
func(15)
736+
721737
def test_main(verbose=None):
722738
test_classes = (
723739
TestPartial,

0 commit comments

Comments
 (0)