msg341239 - (view) |
Author: Raymond Hettinger (rhettinger) *  |
Date: 2019-05-02 00:40 |
Follow the lead of the dataclasses module and allow lru_cache() to be used as a straight decorator rather than as a function that returns a decorator. Both of these would now be supported: @lru_cache def f(x): ... @lru_cache(maxsize=256) def f(x): ... |
|
|
msg341246 - (view) |
Author: Serhiy Storchaka (serhiy.storchaka) *  |
Date: 2019-05-02 04:36 |
I do not like mixing decorators and decorator fabrics. But this can of worms has already been open by dataclasses. The question is whether we want to extend this design to the rest of the stdlib. lru_cache() resisted this change for a long time. |
|
|
msg341255 - (view) |
Author: Eric V. Smith (eric.smith) *  |
Date: 2019-05-02 08:18 |
The 90% use case with dataclasses is satisfied with just "@dataclass", and perhaps the target user there is less sophisticated. But the main difference between @dataclass and @lru_cache is that all of the parameters to @dataclass are keyword-only. Which I did because they are mostly all booleans, and "@dataclass(True, False, True)" isn't very helpful. That's not the case with @lru_cache. Whether that makes a difference for this issue in particular, I'm not sure. I agree that this violates "only one way to do it". But I haven't seen anyone use "@dataclass()", and I've also never seen anyone be confused by the fact that once you want parameters, you change to using parens. For the dataclass case, I think that working both ways has been helpful. |
|
|
msg341266 - (view) |
Author: Stefan Behnel (scoder) *  |
Date: 2019-05-02 14:14 |
I'm generally ok with such APIs. It seems needless to require @lru_cache() def f(): ... when a simple decorator would suffice. I think I might decide otherwise in cases where almost all usages require arguments, but if the no-arguments case is common (and there is no ambiguity in the arguments), then I prefer not requiring parentheses. |
|
|
msg341319 - (view) |
Author: Raymond Hettinger (rhettinger) *  |
Date: 2019-05-03 01:44 |
At Pycon today, I mostly got all positive feedback on this. Apparently py.test already follows this pattern. Another developer said they found the () to be distracting and would welcome not having to use them. |
|
|
msg341391 - (view) |
Author: Eric Snow (eric.snow) *  |
Date: 2019-05-04 15:54 |
FWIW, I've followed this pattern (one function is both decorator and factory) in my own code for quite a while. I've never found it confusing nor has anyone else (that I'm aware) that has used those decorators. One reason I've done decorators this way is because the empty parentheses are a visual distraction to readers. They also imply to readers that more is going on than really is. So I'm in favor of Raymond's plan. |
|
|
msg341392 - (view) |
Author: Eric Snow (eric.snow) *  |
Date: 2019-05-04 15:58 |
As to the issue of positional vs. keyword arguments, keyword arguments make the implementation easier in some cases. Otherwise I haven't seen positional arguments cause much of a problem. |
|
|
msg341446 - (view) |
Author: Serhiy Storchaka (serhiy.storchaka) *  |
Date: 2019-05-05 13:48 |
To clarify, I am not opposing this feature. I had doubts because if the memory does not betray me similar propositions for lru_cache or other decorator fabrics were rejected in past. But times change. |
|
|
msg341569 - (view) |
Author: Pablo Galindo Salgado (pablogsal) *  |
Date: 2019-05-06 17:31 |
I am +1 to this. Making it easier for the case of decorator factories that are called with all the defaults is a very common pattern in the wild. There are even known idioms for how to reduce the indentation of the naive approach (returning partials of the factory). In particular for lru_cache, my experience is that every time I teach this feature, people are confused initially about the '()' at the end of the call. |
|
|
msg343575 - (view) |
Author: Raymond Hettinger (rhettinger) *  |
Date: 2019-05-26 18:27 |
New changeset b821868e6d909f4805499db519ebc2cdc01cf611 by Raymond Hettinger in branch 'master': bpo-36772 Allow lru_cache to be used as decorator without making a function call (GH-13048) https://github.com/python/cpython/commit/b821868e6d909f4805499db519ebc2cdc01cf611 |
|
|