-
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
Fix shadow trait notifications #1188
Conversation
Is the dynamic default that depends on the mutable trait still needed or can it be removed now? traits/traits/trait_converters.py Lines 116 to 122 in 4e435d9
|
@kitchoi It's still needed, to cope with the case where the shadow trait is accessed before the primary trait. |
Let me make sure that we do have tests covering this case ... |
@kitchoi On the other hand, we can now remove that |
Hmm. Travis CI seems to have gone AWOL on recent commits on this PR. |
Closing and re-opening in an attempt to sort out the Travis CI status. |
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. Two questions.
} | ||
|
||
if (PyErr_ExceptionMatches(PyExc_KeyError)) { | ||
PyErr_SetObject(PyExc_AttributeError, name); |
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 conversion from KeyError to AttributeError is removed. Do you know why it was there and that how it is not needed any more?
(Note: there is one like this near the bottom of setattr)
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 line isn't reachable in the C code, so that conversion was never exercised (at least since the move to Python 3 only).
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.
I see. Thank you.
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.
Thanks! Still LGTM
Leaving this unmerged for now; I want to give it a second self-review tomorrow morning, to check that it still makes sense to me. |
That's probably wise... :) |
Merging this after re-review. It's not ideal: one inelegance is that in the case of accessing the shadow trait for the first time (without first accessing the primary trait), |
* Remove unreachable code * Refactor for readability * Unwrap an unnecessarily wrapped line * Another line unwrap * Fix notifications from shadow traits * Remove inappropriate reminder-to-self comment * Additional tests for accessing shadow trait before primary trait * Remove explicit Undefined check in _mapped_trait_default * Flake8: remove unused import * Additional tests (thanks to @kitchoi) * Add changelog entry (cherry picked from commit e960be9)
* Fix truncated List description in documentation (#1178) * Fix truncated List description in documentation * Replace sys.maxint with sys.maxsize everywhere * Add changelog entry (cherry picked from commit 4e435d9) * Tweaks and fixes to setup keywords (#1185) * Tweaks and fixes to setup keywords * Add changelog entry * Fix incorrect PR number (cherry picked from commit ff9ac19) * Fix shadow trait notifications (#1188) * Remove unreachable code * Refactor for readability * Unwrap an unnecessarily wrapped line * Another line unwrap * Fix notifications from shadow traits * Remove inappropriate reminder-to-self comment * Additional tests for accessing shadow trait before primary trait * Remove explicit Undefined check in _mapped_trait_default * Flake8: remove unused import * Additional tests (thanks to @kitchoi) * Add changelog entry (cherry picked from commit e960be9) * Change the 'default default' for Map and PrefixMap (#1189) * Change the 'default default' for Map and PrefixMap * API documentation for the default * Add changelog entry * Add explanatory comment (cherry picked from commit fdcb5f8)
This PR fixes the issue where shadow trait notifications were not being issued on the first change of the primary trait.
The essence of the change is to always call
post_setattr
(if it exists) when accessing a default value. That needs changes in two places:trait_getattr
, where there's already a block that callspost_setattr
, but the call is skipped for mapped traits, for no clear reason; we re-enable that calltrait_setattr
, wheredefault_value_for
is called if necessary to retrieve the old value for notifications. Here we add code to (1) poke the computed default value back onto the dictionary, just like we do already intrait_getattr
, and (2) callpost_setattr
There's scope for refactoring to remove the duplication, but I'd rather do that refactoring post-release, and do the minimum necessary to fix this bug for the release.
Note that this fix required fixing
Map
andPrefixMap
to map a value ofUndefined
correctly; I think that's reasonable:mapped_value
should be prepared to accept any valid value of the principal trait, and currentlyUndefined
is such a value. (But see also #1187)There's also a question of whether in
trait_setattr
we should be issuing notifications with old valueUninitialized
, like we do intrait_getattr
. It makes little difference in practice, since the notifiers don't call listeners whenold
isUninitialized
. We may want to make that change in master, for consistency, but for the bugfix I suggest leaving it out.This builds on #1186, and will be easier to review once that PR is merged.
Fixes #1183