-
-
Notifications
You must be signed in to change notification settings - Fork 33.2k
gh-128576: feat: Add decorator functools.lru_cache
to method tkinter.Misc.winfo_rgb
#128577
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
Conversation
functools.lru_cache
to method tkinter.Misc.winfo_rgb
functools.lru_cache
to method tkinter.Misc.winfo_rgb
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LRU-cached methods should be carefully implemented: see https://docs.python.org/3/faq/programming.html#faq-cache-method-calls. Since Misc
is a mixin class, we should be even more careful.
return self.tk.getint( | ||
self.tk.call('winfo', 'reqwidth', self._w)) | ||
|
||
@functools.lru_cache |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LRU-cached methods do not play well with functools.lru_cache
if __hash__
and __eq__
are not implemented (see https://docs.python.org/3/faq/programming.html#faq-cache-method-calls) because it also caches the instance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To make the lru_cache approach work when the station_id is mutable, the class needs to define the __eq__() and __hash__() methods so that the cache can detect relevant attribute updates:
The above is quoted from: https://docs.python.org/3.13/faq/programming.html#faq-cache-method-calls
But in reality, no matter how the attribute is updated, the return value of the method winfo_rgb
will not change for a particular parameter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is not the return value. It's how the cache is built. The instance itself is cached by lru_cache
. I'm not sure we want to keep them alive. The method will know in advance all the existing instances of Misc that were created and that used this method. This is something we don't want (the cache is a full-fledged dictionary so a reference to those widgets will remain)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now, even if you add those magic methods, the instance will stil be cached. By the way, is it possible to change the color display of the current widget (e.g., directcolor to greyscale) and that this would affect the return value? if so, we cannot cache this method.
I am really not comfortable with caching tk widgets in general. Those objects should be released whenever they can. It would be an overkill to clear the cache when one object has been deleted as well =/
If LRU-caching is possible, instead of storing the instance itself in the cache, we could store the type and the hash of that instance using a class attribute. We could also remove the instance in __del__
so that the hash value can be reused by other objects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By the way, is it possible to change the color display of the current widget (e.g., directcolor to greyscale) and that this would affect the return value?
After my testing, this doesn't affect the return value of the method, if my test method is not wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the result is the same for any widget, perhaps the method should be a class method instead of an instance method. This may eliminate the need to cache instances.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But is this always the same? according to the docs, this depends on the widget itself so I'm afraid we cannot do this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although the documentation says that, I haven't found a way to corroborate what the documentation says, and if there is a way, hopefully it can be pointed out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The result is not constant. It cannot be cached.
If there are no further questions, then I will close the PR and the corresponding issue later. Sorry for the interruption. |
Also, |
winfo_rgb
of tkinter widgets by caching #128576