-
-
Notifications
You must be signed in to change notification settings - Fork 695
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
Remove value parameter from style's apply() method #3159
Conversation
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.
This is a solid implementation of the proposed change; my question is whether the change is the right thing to do in the first place.
I can definitely see the position that passing in the value is, at some level, redundant.
However, it's also... not. With the exception of the iteration in reapply()
, every case where apply()
is being invoked, the code invoking has the current value. By not passing in that value, the attribute value needs to be recomputed - which means hitting a getter, possibly doing some argument name transforms... granted, this isn't a huge overhead, but it's also not nothing. When you add this up over a full style definition, you're adding a bunch of attribute lookup function calls... and not really gaining anything.
So - we do a bunch of code churn and deprecation to gain... code that is (marginally) slower as a result.
It also removes one possible use case - directly invoking apply() with a specific value. We're not actually doing this (nor can I see an obvious usage on the horizon), but the capability does exist.
You could even view passing in the value as part of decoupling the style definition from the applicator process. In that worldview, the fact that the value is being passed in explicitly is a good thing, because it means the process of applying a style value isn't directly coupled to the definition of that style value. Again, this is fairly marginal interpretation... but it exists, and it's faster than the alternative.
Ultimately, I'm not completely sold that the change is worth it. Is there anything specific motivating this, or is this more a case of noticing and cleaning up an apparent redundancy? I'd also be interested in hearing @mhsmith's thoughts on this.
I'll admit, I hadn't thought of that. I do wonder how much of an effect it would actually have, in practice, and whether this might be premature optimization. Or... premature avoidance of de-optimization? 😄 I'm curious to profile a test app now.
Counterpoint: one could say the same thing about passing
Mostly the latter; the name of |
That's definitely fair. I don't think this is/would be a major performance hole; but if we get to a place where it's a line ball decision, it's a notable difference.
True; but in that case |
Also definitely fair!
If I had a nickel for every time either of us conflated styles and nodes, I would have quite a few nickels. I swear I was going cross-eyed working on combining the row and column layout methods. 😆 |
I've done a rudimentary performance test and found surprising results. I made a test file that generates a bunch of widgets and styles, including deprecated names and an Invent synonym. I timed ten runs of it with the main branch, and ten on this one. These were the results, in seconds: Main10.58 Parameter removed10.33 I have no particular insight on why, but it appears that removing the argument and doing more lookups is actually consistently faster. By a very small amount, anyway. |
I agree that's a surprising result. Out of interest - what OS and Python version is this on? I'm wondering if there might be interpreter-level optimisations that make the property lookup faster for some reason. |
Oh hey, I should probably update both of those... |
Python dictionary lookups are highly optimized, and I doubt that adding or removing one from each style application would make any measurable difference. So if it simplifies the code and removes a possible source of confusion, I'm in favor of it. As far as I know, this method has never been in any documentation or example code, so I don't think it requires a deprecation cycle or a public change note. |
Ok - my objection was pretty weakly held; given it's faster, lets do it.
Agreed - and with 0.4.9 out, we've now got additional safety on upgrades. |
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.
One minor tweak to the deprecation comment following the release of 0.4.9, but otherwise this looks good to go.
core/src/toga/style/pack.py
Outdated
def apply(self, prop: str, value: object) -> None: | ||
def apply(self, name: str, value: object = NOT_PROVIDED) -> None: | ||
###################################################################### | ||
# 2025-02: Backwards compatibility for Toga <= 0.4.8 |
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.
# 2025-02: Backwards compatibility for Toga <= 0.4.8 | |
# 2025-02: Backwards compatibility for Toga < 0.5 |
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.
Actually... there's some other comments in the same space that need to be updated in the same way. I'll piggyback those onto this PR.
BaseStyle.apply()
/Pack.apply()
currently accepts two parameters, a name and a value for the property to apply. However, the correct value to pass is always the the value of that property on the style object in question. Thus I propose removing thevalue
parameter.I've also renamed the other parameter from
property
toname
, in line with the consistent naming scheme I've been using in Travertino to distinguish between styles, properties, property names, and property values.PR Checklist: