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 -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/DS72SMJRJNKO3UVDS7ZVKAAPES45PLOQ/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to