Problem
invalidate_cache() called with no arguments on an async-decorated function does not clear the L1 cache in backend=None (L1-only) mode.
Reproduction
from cachekit import cache
import asyncio
call_count = 0
@cache(backend=None, ttl=300)
async def fn(x):
global call_count
call_count += 1
return x * 2
async def test():
global call_count
await fn(5)
print(f"After call 1: computed={call_count}") # 1
await fn(5)
print(f"After call 2: computed={call_count}") # 1 (cached)
# Per-key invalidation works:
await fn.invalidate_cache(5)
await fn(5)
print(f"After invalidate(5), call 3: computed={call_count}") # 2 (recomputed) OK
# No-arg bulk invalidation does NOT work:
await fn.invalidate_cache()
await fn(5)
print(f"After invalidate(), call 4: computed={call_count}") # 2 (still cached!) BUG
asyncio.run(test())
Expected
Call 4 should recompute (computed=3) because invalidate_cache() with no args should clear ALL cached entries for the function.
Actual
Call 4 returns the cached value (computed=2). The no-arg bulk invalidation is a no-op.
Analysis
The no-arg path in the wrapper checks _func_has_params and iterates _cached_keys, but the L1-only mode code path may not be populating _cached_keys correctly, so the snapshot is empty and no entries are invalidated.
Additional issue
cache_clear() raises TypeError for async functions:
TypeError: cache_clear() cannot clear cache for async functions. Use 'await fn.ainvalidate_cache()' instead.
But ainvalidate_cache() (which invalidate_cache aliases to for async functions) doesn't work either, as shown above.
Environment
- cachekit 0.4.0
- Python 3.13
@cache(backend=None) (L1-only mode)
Problem
invalidate_cache()called with no arguments on an async-decorated function does not clear the L1 cache inbackend=None(L1-only) mode.Reproduction
Expected
Call 4 should recompute (computed=3) because
invalidate_cache()with no args should clear ALL cached entries for the function.Actual
Call 4 returns the cached value (computed=2). The no-arg bulk invalidation is a no-op.
Analysis
The no-arg path in the wrapper checks
_func_has_paramsand iterates_cached_keys, but the L1-only mode code path may not be populating_cached_keyscorrectly, so the snapshot is empty and no entries are invalidated.Additional issue
cache_clear()raisesTypeErrorfor async functions:But
ainvalidate_cache()(whichinvalidate_cachealiases to for async functions) doesn't work either, as shown above.Environment
@cache(backend=None)(L1-only mode)