diff options
author | Raymond Hettinger <python@rcn.com> | 2011-10-20 15:57:45 (GMT) |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2011-10-20 15:57:45 (GMT) |
commit | cd9fdfd652cdaca959b1c5d4cddf60d90a331b47 (patch) | |
tree | f714220e35080ef6ad49bc0a88999483fcb0e14a /Lib/functools.py | |
parent | e3455c026afdf5d4448aefde44f7530ea456a9e0 (diff) | |
download | cpython-cd9fdfd652cdaca959b1c5d4cddf60d90a331b47.zip cpython-cd9fdfd652cdaca959b1c5d4cddf60d90a331b47.tar.gz cpython-cd9fdfd652cdaca959b1c5d4cddf60d90a331b47.tar.bz2 |
Issue 13227: Option to make the lru_cache() type specific (suggested by Andrew Koenig).
Diffstat (limited to 'Lib/functools.py')
-rw-r--r-- | Lib/functools.py | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/Lib/functools.py b/Lib/functools.py index 038f284..1abb37a 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -121,12 +121,16 @@ except ImportError: _CacheInfo = namedtuple("CacheInfo", "hits misses maxsize currsize") -def lru_cache(maxsize=100): +def lru_cache(maxsize=100, typed=False): """Least-recently-used cache decorator. If *maxsize* is set to None, the LRU features are disabled and the cache can grow without bound. + If *typed* is True, arguments of different types will be cached separately. + For example, f(3.0) and f(3) will be treated as distinct calls with + distinct results. + Arguments to the cached function must be hashable. View the cache statistics named tuple (hits, misses, maxsize, currsize) with @@ -142,7 +146,7 @@ def lru_cache(maxsize=100): # to allow the implementation to change (including a possible C version). def decorating_function(user_function, - tuple=tuple, sorted=sorted, len=len, KeyError=KeyError): + *, tuple=tuple, sorted=sorted, map=map, len=len, type=type, KeyError=KeyError): hits = misses = 0 kwd_mark = (object(),) # separates positional and keyword args @@ -156,7 +160,12 @@ def lru_cache(maxsize=100): nonlocal hits, misses key = args if kwds: - key += kwd_mark + tuple(sorted(kwds.items())) + sorted_items = tuple(sorted(kwds.items())) + key += kwd_mark + sorted_items + if typed: + key += tuple(map(type, args)) + if kwds: + key += tuple(type(v) for k, v in sorted_items) try: result = cache[key] hits += 1 @@ -177,7 +186,12 @@ def lru_cache(maxsize=100): nonlocal hits, misses key = args if kwds: - key += kwd_mark + tuple(sorted(kwds.items())) + sorted_items = tuple(sorted(kwds.items())) + key += kwd_mark + sorted_items + if typed: + key += tuple(map(type, args)) + if kwds: + key += tuple(type(v) for k, v in sorted_items) with lock: try: result = cache[key] |