Skip to content

Commit c2fde43

Browse files
committed
fixes #582
1 parent 295197f commit c2fde43

File tree

4 files changed

+53
-39
lines changed

4 files changed

+53
-39
lines changed

fastcore/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "1.5.53"
1+
__version__ = "1.5.54"

fastcore/xtras.py

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -686,44 +686,48 @@ def mk_dataclass(cls):
686686
setattr(cls, k, field(default=None))
687687
dataclass(cls, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False)
688688

689-
# %% ../nbs/03_xtras.ipynb 179
689+
# %% ../nbs/03_xtras.ipynb 181
690690
def flexicache(*funcs, maxsize=128):
691691
"Like `lru_cache`, but customisable with policy `funcs`"
692692
def _f(func):
693693
cache,states = {}, [None]*len(funcs)
694694
@wraps(func)
695695
def wrapper(*args, **kwargs):
696-
key = str(args) + str(kwargs)
696+
key = f"{args} // {kwargs}"
697697
if key in cache:
698-
result, states = cache[key]
699-
if not any(func(state) for func, state in zip(funcs, states)):
698+
result,states = cache[key]
699+
if not any(f(state) for f,state in zip(funcs, states)):
700700
cache[key] = cache.pop(key)
701701
return result
702702
del cache[key]
703-
result = func(*args, **kwargs)
704-
cache[key] = (result, [func(None) for func in funcs])
705-
if len(cache) > maxsize: cache.pop(next(iter(cache)))
706-
return result
703+
try: newres = func(*args, **kwargs)
704+
except:
705+
if key not in cache: raise
706+
cache[key] = cache.pop(key)
707+
return result
708+
cache[key] = (newres, [f(None) for f in funcs])
709+
if len(cache) > maxsize: cache.popitem()
710+
return newres
707711
return wrapper
708712
return _f
709713

710-
# %% ../nbs/03_xtras.ipynb 181
714+
# %% ../nbs/03_xtras.ipynb 183
711715
def time_policy(seconds):
712716
"A `flexicache` policy that expires cached items after `seconds` have passed"
713717
def policy(last_time):
714718
now = time()
715719
return now if last_time is None or now-last_time>seconds else None
716720
return policy
717721

718-
# %% ../nbs/03_xtras.ipynb 182
722+
# %% ../nbs/03_xtras.ipynb 184
719723
def mtime_policy(filepath):
720724
"A `flexicache` policy that expires cached items after `filepath` modified-time changes"
721725
def policy(mtime):
722726
current_mtime = getmtime(filepath)
723727
return current_mtime if mtime is None or current_mtime>mtime else None
724728
return policy
725729

726-
# %% ../nbs/03_xtras.ipynb 185
730+
# %% ../nbs/03_xtras.ipynb 187
727731
def timed_cache(seconds=60, maxsize=128):
728732
"Like `lru_cache`, but also with time-based eviction"
729733
return flexicache(time_policy(seconds), maxsize=maxsize)

nbs/03_xtras.ipynb

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2842,7 +2842,25 @@
28422842
},
28432843
{
28442844
"cell_type": "code",
2845-
"execution_count": 1,
2845+
"execution_count": null,
2846+
"metadata": {},
2847+
"outputs": [],
2848+
"source": [
2849+
"d = dict(a=1,b=2)"
2850+
]
2851+
},
2852+
{
2853+
"cell_type": "code",
2854+
"execution_count": null,
2855+
"metadata": {},
2856+
"outputs": [],
2857+
"source": [
2858+
"d.popitem()"
2859+
]
2860+
},
2861+
{
2862+
"cell_type": "code",
2863+
"execution_count": null,
28462864
"metadata": {},
28472865
"outputs": [],
28482866
"source": [
@@ -2853,17 +2871,21 @@
28532871
" cache,states = {}, [None]*len(funcs)\n",
28542872
" @wraps(func)\n",
28552873
" def wrapper(*args, **kwargs):\n",
2856-
" key = str(args) + str(kwargs)\n",
2874+
" key = f\"{args} // {kwargs}\"\n",
28572875
" if key in cache:\n",
2858-
" result, states = cache[key]\n",
2859-
" if not any(func(state) for func, state in zip(funcs, states)):\n",
2876+
" result,states = cache[key]\n",
2877+
" if not any(f(state) for f,state in zip(funcs, states)):\n",
28602878
" cache[key] = cache.pop(key)\n",
28612879
" return result\n",
28622880
" del cache[key]\n",
2863-
" result = func(*args, **kwargs)\n",
2864-
" cache[key] = (result, [func(None) for func in funcs])\n",
2865-
" if len(cache) > maxsize: cache.pop(next(iter(cache)))\n",
2866-
" return result\n",
2881+
" try: newres = func(*args, **kwargs)\n",
2882+
" except:\n",
2883+
" if key not in cache: raise\n",
2884+
" cache[key] = cache.pop(key)\n",
2885+
" return result\n",
2886+
" cache[key] = (newres, [f(None) for f in funcs])\n",
2887+
" if len(cache) > maxsize: cache.popitem()\n",
2888+
" return newres\n",
28672889
" return wrapper\n",
28682890
" return _f"
28692891
]
@@ -2877,7 +2899,7 @@
28772899
},
28782900
{
28792901
"cell_type": "code",
2880-
"execution_count": 2,
2902+
"execution_count": null,
28812903
"metadata": {},
28822904
"outputs": [],
28832905
"source": [
@@ -2892,7 +2914,7 @@
28922914
},
28932915
{
28942916
"cell_type": "code",
2895-
"execution_count": 3,
2917+
"execution_count": null,
28962918
"metadata": {},
28972919
"outputs": [],
28982920
"source": [
@@ -2960,13 +2982,13 @@
29602982
"metadata": {},
29612983
"outputs": [],
29622984
"source": [
2963-
"@timed_cache(seconds=0.1, maxsize=2)\n",
2985+
"@timed_cache(seconds=0.01, maxsize=2)\n",
29642986
"def cached_func(x): return x * 2, time()\n",
29652987
"\n",
29662988
"# basic caching\n",
29672989
"result1, time1 = cached_func(2)\n",
29682990
"test_eq(result1, 4)\n",
2969-
"sleep(0.01)\n",
2991+
"sleep(0.001)\n",
29702992
"result2, time2 = cached_func(2)\n",
29712993
"test_eq(result2, 4)\n",
29722994
"test_eq(time1, time2)\n",
@@ -2983,7 +3005,7 @@
29833005
"test_ne(time3_new, time())\n",
29843006
"\n",
29853007
"# time expiration\n",
2986-
"sleep(0.2)\n",
3008+
"sleep(0.05)\n",
29873009
"_, time4_new = cached_func(4)\n",
29883010
"test_ne(time4_new, time())"
29893011
]
@@ -3018,21 +3040,9 @@
30183040
"split_at_heading": true
30193041
},
30203042
"kernelspec": {
3021-
"display_name": "Python 3 (ipykernel)",
3043+
"display_name": "python3",
30223044
"language": "python",
30233045
"name": "python3"
3024-
},
3025-
"language_info": {
3026-
"codemirror_mode": {
3027-
"name": "ipython",
3028-
"version": 3
3029-
},
3030-
"file_extension": ".py",
3031-
"mimetype": "text/x-python",
3032-
"name": "python",
3033-
"nbconvert_exporter": "python",
3034-
"pygments_lexer": "ipython3",
3035-
"version": "3.11.8"
30363046
}
30373047
},
30383048
"nbformat": 4,

settings.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ author = Jeremy Howard and Sylvain Gugger
88
author_email = [email protected]
99
copyright = fast.ai
1010
branch = master
11-
version = 1.5.53
11+
version = 1.5.54
1212
min_python = 3.7
1313
audience = Developers
1414
language = English

0 commit comments

Comments
 (0)