Issue 27933: functools.lru_cache seems to not work when renaming decorated functions (original) (raw)

Issue27933

Created on 2016-09-01 16:08 by Федор Лянгузов, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
lru_cache_test.py Федор Лянгузов,2016-09-01 16:08 3 tests of functools.lru_cache with one failing
Messages (4)
msg274149 - (view) Author: Федор Лянгузов (Федор Лянгузов) * Date: 2016-09-01 16:08
Greetings, I've encountered strange behavior when using functools.lru_cache as a function (not as a decorator): it is at least miscounting misses, but probably not work at all, when the result of functools.lru_cache()(func) is saved in variable other than 'func'. Consider this snippet: def factorial(n): if n == 0: return 1 else: return n * factorial(n-1) f = functools.lru_cache()(factorial) f(20) print(f.cache_info()) Output should be: CacheInfo(hits=0, misses=21, maxsize=128, currsize=21) Instead it is: CacheInfo(hits=0, misses=1, maxsize=128, currsize=1) I'm using Python 3.5.2 64bit on Windows 7 Professional 64bit. I've written 3 unittests (using built-in module), which are attached as a file. I don't know how to comment them (conceptually, not syntactically), sorry. Fedor
msg274151 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2016-09-01 16:35
This behaviour is expected. The factorial function calls itself, it doesn't call "f", but it is "f" which has the cache. So the call to f() goes through the cache, misses, and then calls factorial(), which has no cache. In effect, what you have written is something like: def factorial(n): if n == 0: return 1 else: return n * factorial(n-1) def f(n): if n in f.cache: return f.cache[n] else: x = f.cache[n] = factorial(n) return x f.cache = lru_cache()
msg274152 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2016-09-01 16:39
In case it isn't obvious, my example is meant to be pseudo-code, not the exact implementation used.
msg274167 - (view) Author: Федор Лянгузов (Федор Лянгузов) * Date: 2016-09-01 18:44
Ok, thank you very much, i've got a little smarter today. Now i understand, that user_function (in this case factorial) is not modified by decorator, it is my job to change factorial to wrapper by assignment. Enlightning.
History
Date User Action Args
2022-04-11 14:58:35 admin set github: 72120
2016-09-01 18:44:15 Федор Лянгузов set status: open -> closedresolution: not a bugmessages: +
2016-09-01 16:39:53 steven.daprano set messages: +
2016-09-01 16:35:53 steven.daprano set nosy: + steven.dapranomessages: +
2016-09-01 16:25:32 abarry set nosy: + rhettinger, ncoghlan
2016-09-01 16:08:44 Федор Лянгузов create