I was surprised to find, when I pass arguments to a function decorated with
`@functools.cache` in different, equivalent ways, the cache does not recognize
them as the same.
counter = itertools.count(1)
@functools.cache
def example(a, b, c=0):
return (next(counter), a, b, c)
example(1, 2) # => (1, 1, 2, 0)
example(1, b=2) # => (2, 1, 2, 0)
example(1, 2, 0) # => (3, 1, 2, 0)
When I wrote my own implementation as a coding exercise, I noticed the same
weakness while testing it and solved that by having the decorator function get
the signature of the decorated function, then use the bind method of the
signature to bind the parameter values, then call the apply_defaults method on
the bound arguments, and then finally, use the args and kwargs properties of
the bound arguments to make the cache key.
It seems like functools.cache should do the same thing. If it is undesirable
for that to be the default behavior, then it could be optional (e.g.
@functools.cache(normalize=True) ).
I have not tested to see if functools.lru_cache has the same issue. I presume
that it does, so my suggestion would apply to that as well.
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/DS72SMJRJNKO3UVDS7ZVKAAPES45PLOQ/
Code of Conduct: http://python.org/psf/codeofconduct/