Transform ID:Documentation Index
Fetch the complete documentation index at: https://docs.refactron.dev/llms.txt
Use this file to discover all available pages before exploring further.
lru_cache_to_cache
Language: Python
What it does
Rewrites the unbounded-cache idiom@functools.lru_cache(maxsize=None) to the equivalent @functools.cache decorator added in Python 3.9. Handles both the attribute form (@functools.lru_cache(...)) and the bare-name form (@lru_cache(...) after from functools import lru_cache), and updates the from functools import … line so it imports cache (renamed if lru_cache is no longer used, augmented alongside it if a finite-cap site survives). The sidecar (src/transform/transforms/python/_py/lru_cache_to_cache.py) drives the LibCST rewrite.
Detector pattern
The detector atsrc/analyze/detectors/python/lru-cache-maxsize-none.ts matches decorator call expressions whose function is lru_cache or functools.lru_cache AND whose argument list is exactly one keyword argument maxsize=None. Bare @lru_cache(), @lru_cache(128), and @lru_cache(maxsize=None, typed=True) are intentionally not flagged.
Preconditions
python_version_too_low— refuses when the project’s resolved Python version is< 3.9(or unknown).functools.cacheis a 3.9 addition; pin via thepythonVersionconfig key.- The decorator call must be exactly
lru_cache(maxsize=None)— notyped=True, no finitemaxsize, no zero-arg form (@lru_cache()defaults tomaxsize=128, not unbounded, so it is not a safe@cachesubstitute). - Bare-name decorators only resolve when
from functools import lru_cache(or the no-opas lru_cache) is in scope. A genuine rebinding (from functools import lru_cache as cache_dec) is left untouched — rewriting under an alias would invalidate the existing call sites.
Before / after
from functools import … line is also updated:
@lru_cache(128) site survives in the same file, the import is augmented instead of renamed: from functools import lru_cache, cache.
Edge cases NOT handled (skip via precondition)
@lru_cache()(zero args) — semantically equivalent to@lru_cache(maxsize=128)per CPython docs; not unbounded, so swapping in@cachewould change behaviour.@lru_cache(128)/@lru_cache(maxsize=1024)— finite caps;@cachewould grow without bound.@lru_cache(maxsize=None, typed=True)— type-discriminated caching has no@cacheequivalent.- Decorators using a renamed import (
from functools import lru_cache as cache_dec) — left alone because we can’t rewrite the alias’s call sites.
Version gating is hard — if
pythonVersion is null and not detectable from pyproject.toml’s requires-python, the transform refuses rather than guess. Set "pythonVersion": "3.9" (or higher) in .refactronrc.json to unlock the rewrite.