-
-
Notifications
You must be signed in to change notification settings - Fork 3k
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
[doc]Update doc of AliasProperty #6316
Conversation
kivy/properties.pyx
Outdated
If your want to cache the value returned by getter then pass `cache=True`. | ||
Usually `bind` list should contain all Kivy properties used in getter | ||
method. If you're setting a property from `bind` list then you shouldn't | ||
`return True` in setter as that will dispatch new value twice. |
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 not necessarily correct. For example:
def getter(self):
return self._value
def setter(self, value):
self.x = value * 25
self._value = value
return True
prop = AliasProperty(getter, setter, bind=['x'], cache=True)
Even though we set x
in the setter, we still need to return True, otherwise it will have the incorrect value.
So we shouldn't advise people to return True/False based on what was set in the setter, but rather always recommend to return True if it was changed. The original comment
If
x
were to be an instance level attribute and not Kivy property then you have to returnTrue
from setter to dispatch value ofright
is also misleading in this way and should instead just say that it needs to return True if we want it to dispatch.
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 are so many cases with AliasProperty
.
If you swap x
and _value
lines in setter:
def setter(self, value):
self._value = value
self.x = value * 25
return True
and still return True
then prop
value will be dispatched twice with same value, first when x
is set and again when True
is returned.
Do you have idea on how to better phrase that paragraph so that is clear when user should return True
? I'm right now out of ideas :)
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.
Maybe we can update set
method of AliasProperty
from this:
cpdef set(self, EventDispatcher obj, value):
cdef PropertyStorage ps = obj.__storage[self._name]
if ps.setter(obj, value):
if self.use_cache:
if ps.alias_initial:
ps.alias_initial = 0
ps.value = ps.getter(obj)
self.dispatch(obj)
elif self.force_dispatch:
self.dispatch(obj)
to this:
cpdef set(self, EventDispatcher obj, value):
cdef PropertyStorage ps = obj.__storage[self._name]
if ps.setter(obj, value):
cdef int changed = 1
if self.use_cache:
changed = 0
dvalue = ps.getter(obj)
if dvalue != ps.value:
if ps.alias_initial:
ps.alias_initial = 0
ps.value = dvalue
changed = 1
if changed:
self.dispatch(obj)
elif self.force_dispatch:
self.dispatch(obj)
Then we can tell the user to return True
in setter to accept value, but value will be dispatched only if it has changed.
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.
You are right that it would be dispatched twice, but I think it's ok. It's better to dispatch multiple times (after all that's how it would generally work), then not dispatch when needed. Kivy doesn't really make a guarantee that properties won't dispatch even if the value is the same (although we do try to prevent that if possible). We just promise that properties will definitely dispatch if they are changed.
As you say, it's hard to say something meaningful here in the docs because we could have many different situations. That's why I think saying something like, if you return True it will cause a dispatch which one should do to when the property value has changed, but keep in mind that the property could already have dispatched the changed value if a kivy property the alias property is bound was set in the setter, causing a second dispatch if the setter returns True.
is better. Because this makes no recommendation, but just describes the behavior.
We can definitely change set
to what you suggest, but that would change the interpretation of returning True from meaning we should dispatch to mean that the value may have changed so maybe we should dispatch. This change may be a compatibility break and I'm not sure it is worth to do unless this comes up as an actual issue.
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.
Ok, I'll update pr with your suggestions.
kivy/properties.pyx
Outdated
Function to use as a property setter. Callbacks bound to the | ||
alias property won't be called when the property is set (e.g. | ||
`right = 10`), unless the setter returns `True`. | ||
Function to use as a property setter. |
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.
I'm not sure why you removed 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.
Removed sentence is partially true, because callbacks will be also dispatched when some of binded properties changes and getter returns new value.
I thought that it would be better to explain in text above how setter should work and don't repeat same thing in Parameters
section.
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.
I think it is better to give a very short summary here, even if it was already explained earlier because sometimes I don't get the full implication from the example and I want a short summary to make sure I understood the implications. Repeating it twice gives me chance to make sure I understood by comparing what I understand the two places to say.
So I'd say it's good to fix it to give a very short and concise summary here and for bind
.
Properties to observe for changes, as property name strings. | ||
Changing values of this properties will dispatch value of the | ||
alias property. | ||
Properties to observe for changes as property name strings. |
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.
I'm not sure why you removed this either?
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.
Same as the answer above. That sentence is partially true as new value will be dispatched only when binded property changes and getter returns new value.
If getter is doing something like clamping (min(max(x, min_value), max_value)
) and returns the same value then property won't get dispatched.
Improved doc of
AliasProperty
better explainssetter
method andbind
argument.