summaryrefslogtreecommitdiff
path: root/Lib/functools.py
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2013-03-01 23:21:00 -0800
committerRaymond Hettinger <python@rcn.com>2013-03-01 23:21:00 -0800
commit6c5b2d8497dbcab5bc05ff2dd76b213463e5d929 (patch)
tree38e96bd844c7f8705f29ab090b682350bf9a8852 /Lib/functools.py
parentef063cebb5fe2ec876f0f7b809996f10b68b19f0 (diff)
parent0000236722611d64d478b722060430ca7e1e39de (diff)
downloadcpython-6c5b2d8497dbcab5bc05ff2dd76b213463e5d929.tar.gz
Merge
Diffstat (limited to 'Lib/functools.py')
-rw-r--r--Lib/functools.py45
1 files changed, 34 insertions, 11 deletions
diff --git a/Lib/functools.py b/Lib/functools.py
index 36466f9c17..a019268d4f 100644
--- a/Lib/functools.py
+++ b/Lib/functools.py
@@ -11,7 +11,10 @@
__all__ = ['update_wrapper', 'wraps', 'WRAPPER_ASSIGNMENTS', 'WRAPPER_UPDATES',
'total_ordering', 'cmp_to_key', 'lru_cache', 'reduce', 'partial']
-from _functools import partial, reduce
+try:
+ from _functools import reduce
+except ImportError:
+ pass
from collections import namedtuple
try:
from _thread import RLock
@@ -140,6 +143,29 @@ except ImportError:
################################################################################
+### partial() argument application
+################################################################################
+
+def partial(func, *args, **keywords):
+ """new function with partial application of the given arguments
+ and keywords.
+ """
+ def newfunc(*fargs, **fkeywords):
+ newkeywords = keywords.copy()
+ newkeywords.update(fkeywords)
+ return func(*(args + fargs), **newkeywords)
+ newfunc.func = func
+ newfunc.args = args
+ newfunc.keywords = keywords
+ return newfunc
+
+try:
+ from _functools import partial
+except ImportError:
+ pass
+
+
+################################################################################
### LRU Cache function decorator
################################################################################
@@ -205,9 +231,8 @@ def lru_cache(maxsize=128, typed=False):
PREV, NEXT, KEY, RESULT = 0, 1, 2, 3 # names for the link fields
def decorating_function(user_function):
-
cache = {}
- hits = misses = currsize = 0
+ hits = misses = 0
full = False
cache_get = cache.get # bound method to lookup a key or return None
lock = RLock() # because linkedlist updates aren't threadsafe
@@ -227,7 +252,7 @@ def lru_cache(maxsize=128, typed=False):
def wrapper(*args, **kwds):
# simple caching without ordering or size limit
- nonlocal hits, misses, currsize
+ nonlocal hits, misses
key = make_key(args, kwds, typed)
result = cache_get(key, sentinel)
if result is not sentinel:
@@ -236,14 +261,13 @@ def lru_cache(maxsize=128, typed=False):
result = user_function(*args, **kwds)
cache[key] = result
misses += 1
- currsize += 1
return result
else:
def wrapper(*args, **kwds):
# size limited caching that tracks accesses by recency
- nonlocal root, hits, misses, currsize, full
+ nonlocal root, hits, misses, full
key = make_key(args, kwds, typed)
with lock:
link = cache_get(key)
@@ -280,23 +304,22 @@ def lru_cache(maxsize=128, typed=False):
last = root[PREV]
link = [last, root, key, result]
cache[key] = last[NEXT] = root[PREV] = link
- currsize += 1
- full = (currsize == maxsize)
+ full = (len(cache) == maxsize)
misses += 1
return result
def cache_info():
"""Report cache statistics"""
with lock:
- return _CacheInfo(hits, misses, maxsize, currsize)
+ return _CacheInfo(hits, misses, maxsize, len(cache))
def cache_clear():
"""Clear the cache and cache statistics"""
- nonlocal hits, misses, currsize, full
+ nonlocal hits, misses, full
with lock:
cache.clear()
root[:] = [root, root, None, None]
- hits = misses = currsize = 0
+ hits = misses = 0
full = False
wrapper.cache_info = cache_info