-
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
Add warning while observing container items with comparison mode set to equality #1117
Conversation
Confirmed the test suite is still quiet: That is because tests on observers such as traits/traits/observers/tests/test_list_item_observer.py Lines 231 to 239 in 78bc0d9
The warning requires an observer observing a CTrait being followed by an observer observing container items. We will likely need integration tests bringing together different observers, but that will be another PR, and those tests will run into this warning if |
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.
Code looks okay, modulo a couple of nitpicks, but I'm wondering what the long-term picture looks like here.
If we end up in a place where code has transitioned to using observe
, we're going to see a lot of comparison_mode=ComparisonMode.identity
noise in our HasTraits
classes. Any thoughts about how we might eventually get rid of that noise?
One possible plan is to eventually make comparison_mode=ComparisonMode.identity
the default for these trait types; we'd have to do that after most code had transitioned to using observe
, and with suitable warnings (probably over several releases).
Another possibility (orthogonal to the first) would be to provide convenience aliases: e.g., IList(...) = List(..., comparison_mode=ComparisonMode.identity)
. (Thinking "I" for "Identity", but we'd have to figure out the right name.)
""" | ||
ctrait = object.traits()[name] | ||
|
||
def has_container_trait(ctrait): |
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.
Please pull this out to a module-level function; I don't think there's any need for it to be a nested function here.
|
||
if (not ctrait.is_property | ||
and has_container_trait(ctrait) | ||
and ctrait.comparison_mode > ComparisonMode.identity): |
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.
We shouldn't rely on ordering being meaningful for ComparisonMode
entries. Let's instead check for ComparisonMode.equality
directly. If you want to make this code more defensive against possible future additions to ComparisonMode
, you could raise NotImplementedError
for comparison modes other than the known three.
Yes I think both of these ideas are nice and can work together. In particular, I agree that it would be best to have the default comparison mode set to identity eventually. And I agree that manually adding the Are you thinking about something like this?:
After all these, I think the warning might still need to stay in case someone really needs the comparison mode to be equality and they need Note there is also a scenario where Shall we merge this PR and continue the discussion in a separate issue? |
I'm sorry, the "equality" in this sentence should be "identity". Updated the comment. |
Let's do that. |
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.
LGTM
Opened #1122 |
Part of #977
This PR adds a warning when item changes in a list/dict/set are observed, if the list/dict/set is a top-level container and the
comparison_mode
is set to equality.Motivation: When a new container is assigned to a trait where the comparison mode is set to equality (the default), no change event will be fired if the new container compared equally to the old one. Consequently, mutation and extended trait change cannot be observed on the new container, and the old container (if it is still around) will continue to emit notifications. This would be an unexpected behaviour.
Changing the default comparison mode is going to break code. So instead, the warning instructs users to fix this by setting
comparison_mode
to identity, like this:Note that the warning is not emitted until an observer is requested, this is such that we don't create warnings for existing code using
on_trait_change
. The downside is that the warning occurs late.Checklist
docs/source/traits_api_reference
) <--- Not sure where this can goUpdate User manual (: Will be in a separate PRdocs/source/traits_user_manual
)Update type annotation hints intraits-stubs