diff options
Diffstat (limited to 'Lib/functools.py')
-rw-r--r-- | Lib/functools.py | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/Lib/functools.py b/Lib/functools.py index 85ea257..092b1ab 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -21,7 +21,8 @@ except: # update_wrapper() and wraps() are tools to help write # wrapper functions that can handle naive introspection -WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__', '__annotations__') +WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__qualname__', '__doc__', + '__annotations__') WRAPPER_UPDATES = ('__dict__',) def update_wrapper(wrapper, wrapped, @@ -114,14 +115,23 @@ def cmp_to_key(mycmp): __hash__ = None return K +try: + from _functools import cmp_to_key +except ImportError: + pass + _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 @@ -137,7 +147,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 @@ -151,7 +161,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 @@ -172,7 +187,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] |