lru_cache has the benefit of being explicit about the replacement policy. So I find it more appropriate in cases where I want a size limit in the cache which, for me, is almost always.
I’m not sure use cases you see caches in, but any long running process should likely have a size limit on the cache.
It still doesn't sit right with me that they still don't offer an option to enable deep copying the results. Using it with a function that returns a mutable object means that the "cached" value can actually be modified.
That depends on the semantics. If the function returns the Person object with a particular name (obtained from an expensive dB query) then you want the mutated Person returned, not the now stale value that was returned on the previous call to the function.