Issue 32001: @lru_cache needs to be called with ()

Issue32001

Created on 2017-11-10 10:20 by ataraxy, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (5)
msg306016 - (view) Author: Tom Hale (ataraxy) Date: 2017-11-10 10:20
This comes from a question I raised on StackOverflow:
https://stackoverflow.com/q/47218313/5353461

I've copied the text below

=====================================================================
=====================================================================


The [documentation for `lru_cache`](https://docs.python.org/3/library/functools.html#functools.lru_cache) gives the function definition:

>     @functools.lru_cache(maxsize=128, typed=False)

This says to me that `maxsize` is optional.

However, it doesn't like being called without an argument:

    Python 3.6.3 (default, Oct 24 2017, 14:48:20) 
    [GCC 7.2.0] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import functools
    >>> @functools.lru_cache
    ... def f(): ...
    ... 
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/lib/python3.6/functools.py", line 477, in lru_cache
        raise TypeError('Expected maxsize to be an integer or None')
    TypeError: Expected maxsize to be an integer or None
     >>> 

Calling with an argument is fine:

    >>> @functools.lru_cache(8)
    ... def f(): ...
    ... 
    >>> 

Am I misreading the documentation?

=====================================================================
=====================================================================

The answer presented this solution:

    if callable(maxsize):
        def decorating_function(user_function):
            wrapper = _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo)
            return update_wrapper(wrapper, user_function)
        return decorating_function(max_size) # yes, max_size is the function in this case O:)


=====================================================================
=====================================================================

Would you accept a PR based on this solution?
msg306018 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-11-10 10:35
I'm -1. The beginner can make use lru_cache incorrectly the first time, but nobody will make this mistake twice. It is not worth to complicate the code (by the way, your code contains a bug) for saving from at most one mistake for all life.

"Special cases aren't special enough to break the rules."
msg306040 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2017-11-10 17:30
I remember seeing code needed to make a decorator that works with and without parens and finding it quite obscure and confusing for a long time.  When you understand the distinction between, things become clear and simple again.  I like that the stdlib keeps that distinction.

We could change the doc to include an example without parameters.
We may also make sure to call lru_cache a decorator factory, with a glossary link or link to decorator reference doc.
msg306041 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-11-10 18:14
One such decorator was added in 3.7: xmlrpc.server.register_function (see issue7769). I don't think lru_cache should follow this example.

There are few cases in which such obscure decorators are more or less appropriate:

1. The function initially was not a decorator, and now it can be used as a decorator, but we need to pass additional optional arguments.

2. The decorator initially didn't take arguments, but we need to pass optional arguments now.

3. The majority of usages of the decorator don't take arguments.

Maybe needed to satisfy more than one of the above conditions.
msg306059 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2017-11-10 23:19
Marking this as rejected.  We specifically added a test and error message for this particular misuse of lru_cache.
History
Date User Action Args
2022-04-11 14:58:54adminsetgithub: 76182
2017-11-10 23:19:43rhettingersetstatus: open -> closed
resolution: rejected
messages: + msg306059

stage: resolved

2017-11-10 18:14:05serhiy.storchakasetmessages: + msg306041
2017-11-10 17:30:35eric.araujosetnosy: + eric.araujo
messages: + msg306040
2017-11-10 10:35:35serhiy.storchakasetnosy: + rhettinger, serhiy.storchaka
messages: + msg306018
2017-11-10 10:20:30ataraxycreate