mirror of
https://github.com/python/cpython.git
synced 2025-09-27 18:59:43 +00:00
Issue 13177: Make tracebacks more readable by avoiding chained exceptions in the lru_cache.
This commit is contained in:
parent
9be57231dd
commit
4b779b3785
3 changed files with 39 additions and 15 deletions
|
@ -141,7 +141,7 @@ def lru_cache(maxsize=100):
|
||||||
|
|
||||||
hits = misses = 0
|
hits = misses = 0
|
||||||
kwd_mark = (object(),) # separates positional and keyword args
|
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:
|
if maxsize is None:
|
||||||
cache = dict() # simple cache without ordering or size limit
|
cache = dict() # simple cache without ordering or size limit
|
||||||
|
@ -155,13 +155,15 @@ def lru_cache(maxsize=100):
|
||||||
try:
|
try:
|
||||||
result = cache[key]
|
result = cache[key]
|
||||||
hits += 1
|
hits += 1
|
||||||
|
return result
|
||||||
except KeyError:
|
except KeyError:
|
||||||
result = user_function(*args, **kwds)
|
pass
|
||||||
cache[key] = result
|
result = user_function(*args, **kwds)
|
||||||
misses += 1
|
cache[key] = result
|
||||||
|
misses += 1
|
||||||
return result
|
return result
|
||||||
else:
|
else:
|
||||||
cache = OrderedDict() # ordered least recent to most recent
|
cache = OrderedDict() # ordered least recent to most recent
|
||||||
cache_popitem = cache.popitem
|
cache_popitem = cache.popitem
|
||||||
cache_renew = cache.move_to_end
|
cache_renew = cache.move_to_end
|
||||||
|
|
||||||
|
@ -171,18 +173,20 @@ def lru_cache(maxsize=100):
|
||||||
key = args
|
key = args
|
||||||
if kwds:
|
if kwds:
|
||||||
key += kwd_mark + tuple(sorted(kwds.items()))
|
key += kwd_mark + tuple(sorted(kwds.items()))
|
||||||
try:
|
with lock:
|
||||||
with lock:
|
try:
|
||||||
result = cache[key]
|
result = cache[key]
|
||||||
cache_renew(key) # record recent use of this key
|
cache_renew(key) # record recent use of this key
|
||||||
hits += 1
|
hits += 1
|
||||||
except KeyError:
|
return result
|
||||||
result = user_function(*args, **kwds)
|
except KeyError:
|
||||||
with lock:
|
pass
|
||||||
cache[key] = result # record recent use of this key
|
result = user_function(*args, **kwds)
|
||||||
misses += 1
|
with lock:
|
||||||
if len(cache) > maxsize:
|
cache[key] = result # record recent use of this key
|
||||||
cache_popitem(0) # purge least recently used cache entry
|
misses += 1
|
||||||
|
if len(cache) > maxsize:
|
||||||
|
cache_popitem(0) # purge least recently used cache entry
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def cache_info():
|
def cache_info():
|
||||||
|
|
|
@ -655,6 +655,22 @@ class TestLRU(unittest.TestCase):
|
||||||
self.assertEqual(fib.cache_info(),
|
self.assertEqual(fib.cache_info(),
|
||||||
functools._CacheInfo(hits=0, misses=0, maxsize=None, currsize=0))
|
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):
|
def test_main(verbose=None):
|
||||||
test_classes = (
|
test_classes = (
|
||||||
TestPartial,
|
TestPartial,
|
||||||
|
|
|
@ -46,6 +46,10 @@ Library
|
||||||
- Issue #13158: Fix decoding and encoding of GNU tar specific base-256 number
|
- Issue #13158: Fix decoding and encoding of GNU tar specific base-256 number
|
||||||
fields in tarfile.
|
fields in tarfile.
|
||||||
|
|
||||||
|
- Issue #13177: Functools lru_cache() no longer calls the original function
|
||||||
|
inside an exception handler. This makes tracebacks easier to read because
|
||||||
|
chained exceptions are avoided.
|
||||||
|
|
||||||
- Issue #13025: mimetypes is now reading MIME types using the UTF-8 encoding,
|
- Issue #13025: mimetypes is now reading MIME types using the UTF-8 encoding,
|
||||||
instead of the locale encoding.
|
instead of the locale encoding.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue