Index: Lib/functools.py =================================================================== --- Lib/functools.py (revision 86907) +++ Lib/functools.py (working copy) @@ -119,6 +119,9 @@ def lru_cache(maxsize=100): """Least-recently-used cache decorator. + If *maxsize* is set to None, the LRU features are disabled and the cache + can grow without bound. + Arguments to the cached function must be hashable. View the cache statistics named tuple (hits, misses, maxsize, currsize) with @@ -136,20 +139,38 @@ def decorating_function(user_function, tuple=tuple, sorted=sorted, len=len, KeyError=KeyError): - cache = OrderedDict() # ordered least recent to most recent - cache_popitem = cache.popitem - cache_renew = cache.move_to_end + if maxsize is None: + cache = dict() + else: + cache = OrderedDict() # ordered least recent to most recent + cache_popitem = cache.popitem + cache_renew = cache.move_to_end hits = misses = 0 kwd_mark = object() # separates positional and keyword args lock = Lock() @wraps(user_function) - def wrapper(*args, **kwds): + def non_lru_wrapper(*args, **kwds): nonlocal hits, misses key = args if kwds: key += (kwd_mark,) + tuple(sorted(kwds.items())) try: + result = cache[key] + hits += 1 + except KeyError: + result = user_function(*args, **kwds) + cache[key] = result + misses += 1 + return result + + @wraps(user_function) + def lru_wrapper(*args, **kwds): + nonlocal hits, misses + key = args + if kwds: + key += (kwd_mark,) + tuple(sorted(kwds.items())) + try: with lock: result = cache[key] cache_renew(key) # record recent use of this key @@ -163,6 +184,8 @@ cache_popitem(0) # purge least recently used cache entry return result + wrapper = non_lru_wrapper if maxsize is None else lru_wrapper + def cache_info(): """Report cache statistics""" with lock: