-
Notifications
You must be signed in to change notification settings - Fork 85
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
Value-changing getters on dynamic Trait types are problematic #1390
Comments
Here's an example of the problematic behaviour: our dynamic Enum value is modified at get time for a single instance, but not for an Enum inside a List: from traits.api import Enum, HasStrictTraits, List, Str
class OrderRecord(HasStrictTraits):
meal_choices = List(Str)
single_customer_order = Enum(values="meal_choices")
group_order = List(Enum(values="meal_choices"))
# Works as expected: order is modified when the menu changes.
record = OrderRecord(meal_choices=["curry", "cornflakes", "carrots"])
record.single_customer_order = "curry"
# "Sorry Sir, the curry is off. Perhaps you'd like the cornflakes instead?"
record.meal_choices.remove("curry")
assert record.single_customer_order == "cornflakes" # passes, as expected
# Fails: the list isn't modified when the menu changes.
record = OrderRecord(meal_choices=["curry", "cornflakes", "carrots"])
record.group_order = ["carrots", "curry"]
record.meal_choices.remove("curry")
assert record.group_order == ["carrots", "cornflakes"] # unexpected failure |
In theory, we could rework the getters for Lists, Tuples, etc. to invoke the getters for individual traits. In practice, that's going to be a lot of work, and it's really not clear that it's the right thing to do. An alternative may be to deprecate the value-changing behaviour, or at least warn about it in the documentation and note that it's not wise to depend on it. |
To elaborate on this: the main problem with this get-time value changing is that the apparent value of the trait will have changed, but observers will not receive any notification about the value change. An additional issue is the surprising non-stickiness of the change: in the original example, if I add |
A few points from discussion in another channel: To summarize the issue: we have a trait where the validity of the value is constrained by the value of other traits.
Part of the "solution" here would likely be to provide recommended patterns for use-cases where the constraints do need to change dynamically. Those patterns could be in the form of documentation, or something closer to re-usable code. A likely pattern for the solution would involve trait listeners on the constraints that reset the constrained value appropriately. |
The
Enum
andRange
trait types have trait getters which can report a different value from the one stored.One way in which this is problematic (there are others) is that if those Trait types are inside another container, the
get
magic is no longer invoked.Example to follow shortly.
The text was updated successfully, but these errors were encountered: