-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
False positive about @cache on Enum methods #7857
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
As far as I know the behaviour isn't different for |
From the side of # pylint: disable=missing-docstring
from enum import Enum
from functools import cache
class EnumClass(Enum):
A = 1
@cache
def func(self, text: str) -> None:
print(text)
class Class:
@cache
def func(self, text: str) -> None:
print(text)
EnumClass(1).func("printed once")
EnumClass(1).func("printed once")
Class().func("printed twice")
Class().func("printed twice") |
Or maybe an even clearer demonstration: # pylint: disable=missing-docstring
from enum import Enum
from functools import cache
from typing import Any
class EnumClass(Enum):
A = 1
class Class:
pass
@cache
def func(_: Any, text: str) -> None:
print(text)
func(EnumClass(1), "printed once")
func(EnumClass(1), "printed once")
func(Class(), "printed twice")
func(Class(), "printed twice") |
Both of these examples don't really show what this message is warning against. Defining the I think that from enum import Enum
from functools import cache
class A:
def __del__(self):
print("A.__del__")
def func(self, x):
print("A.func")
class B:
def __del__(self):
print("B.__del__")
@cache
def func(self, x):
print("B.func")
class C(Enum):
A = 1
def __del__(self):
print("C.__del__")
def func(self, x):
print("C.func")
class D(Enum):
A = 1
def __del__(self):
print("D.__del__")
@cache
def func(self, x):
print("D.func")
A().func(1)
B().func(1)
C(1).func(1)
D(1).func(1) ❯ python -i test.py
A.func
A.__del__
B.func
C.func
D.func
>>>
C.__del__
D.__del__
B.__del__
|
I assumed this message warns against an indefinitely growing cache, and my example shows that the cache entries for an enum are finite. This might be stuff for another issue, but I ignored the actual wording of the message, because it doesn't make any sense to me:
|
Like the documentation shows this is not the case. It is not about an infinitely large cache, but about the garbage collection of the stuff that is in the cache.
How would we rephrase this then? Does the extended description in the documentation help?
The issue warns about decorating methods since it is unconsidered unexpected behaviour that |
If I annotate a function with The example in the documentation is contrived, because |
In that case it might be better to explicitly disable the warning then. Not all messages fit all Python code.
It's not based on whether the argument is called
In documentation examples we always focus on issue. Although other pylint warnings might be raisable we don't show those to allow us to focus the example on a specific message. It feels as if you're aware of the behaviour of |
I thought the warning was about both issues combined (growing cache and no garbage collection) ? As we say in the doc:
We don't have an easy way to detect that a class is a singleton (there's no official way to make a class a singleton) so we accepted that there could be some false positives. But if enums are known singletons we should not raise afaiu. |
Without knowing the code, it very much seems like the warning is only triggered for functions, not methods, and doesn't depend on the kind of arguments.
My point is that the raised warning is merely a consequence of the actual issue.
To be precise, the members of an enum are singletons, so you can have multiple instances of |
@RumovZ would this be a better example to illustrate the issue ? bad: import functools
class Fibonnaci:
result = []
@functools.lru_cache(maxsize=None) # [method-cache-max-size-none]
def fibonacci(self, n):
if n in {0, 1}:
self.result.append(n)
self.result.append(self.fibonacci(n - 1) + self.fibonacci(n - 2)) good: import functools
@functools.cache
def cached_fibonacci(n):
if n in {0, 1}:
return n
return cached_fibonacci(n - 1) + cached_fibonacci(n - 2)
class Fibonnaci:
result = []
def fibonacci(self, n):
self.result.append(cached_fibonacci(n)) |
I think it's better, but import functools
@functools.lru_cache(maxsize=None) # [method-cache-max-size-none]
def fibonacci(result, n):
if n in {0, 1}:
result.append(n)
result.append(fibonacci(result, n - 1) + fibonacci(result, n - 2)) This really shows that the problem is not Maybe I could summarise my point of view like this: As this lint has both false positives and negatives, it probably warns against the wrong thing. |
I think we are starting to confuse things here. In your original post you pointed out an issue with this warning, which we should solve: The rest of this discussion is taking this warning much broader. As far as I see it there is no intent of expanding this warning to also start checking other functions for redundant variables as that is simply too difficult. It just invites you to rewrite methods to no longer use |
Thank you for clarifying @RumovZ . I created #7861 to make the documentation better feel free to review :) As @DanielNoord said, the remaining issue is to exclude known builtin singleton from the check (just enum ?). |
…iting from ``Enum``. Closes pylint-dev#7857
…iting from ``Enum``. Closes pylint-dev#7857
For methods inheriting from ``Enum``. Closes #7857 Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
Bug description
Configuration
No response
Command used
Pylint output
Expected behavior
Pylint shouldn't complain about this, the code is perfectly fine.
Repeated calls to
Class(1).func()
will not grow the cache, nor prevent anything from being garbage collected.Pylint version
OS / Environment
No response
Additional dependencies
No response
The text was updated successfully, but these errors were encountered: