-
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
Allow assigning None to CTrait.post_setattr #833
Allow assigning None to CTrait.post_setattr #833
Conversation
Codecov Report
@@ Coverage Diff @@
## master #833 +/- ##
=========================================
Coverage ? 72.45%
=========================================
Files ? 51
Lines ? 6367
Branches ? 1278
=========================================
Hits ? 4613
Misses ? 1360
Partials ? 394
Continue to review full report at Codecov.
|
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.
The code change looks good, but I think we could do with a better test here.
traits/ctraits.c
Outdated
@@ -4333,6 +4333,10 @@ post_setattr_trait_python( | |||
trait_object *trait, has_traits_object *obj, PyObject *name, | |||
PyObject *value) | |||
{ | |||
if (trait->py_post_setattr == NULL) { |
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.
Is this code branch ever exercised? If it is, that's a coding error, so we should be raising some sort of exception here. But I suspect it's not.
What happens if you add an assert(0)
here, compile with -UNDEBUG
, and then run the test suite?
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 triggered if post_setattr is set to NULL whenever py_post_setattr is NULL.
As you suspected, the branch execution was a coding error caused by changes in this PR.
traits/ctraits.c
Outdated
@@ -4841,9 +4845,13 @@ get_trait_post_setattr(trait_object *trait, void *closure) | |||
static int | |||
set_trait_post_setattr(trait_object *trait, PyObject *value, void *closure) | |||
{ | |||
if (!PyCallable_Check(value)) { | |||
if(value == Py_None){ |
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.
Style nit: add a space before the "(" and another after the ")".
PyErr_SetString( | ||
PyExc_ValueError, "The assigned value must be callable."); | ||
PyExc_ValueError, "The assigned value must be callable or None."); |
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.
So I think we need to do more here: if we're setting None
as a value for py_post_setattr
, then having trait->post_setattr
be post_setattr_trait_python
is wrong. Instead, we want trait->post_setattr
to be NULL
as well.
The invariant should be that if trait->post_setattr
is post_setattr_trait_python
, then py_post_setattr
is non-NULL.
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're getting there, but this still isn't quite right: we should ensure that when py_post_setattr
is NULL
, then post_setattr
is NULL
, too.
Stepping back a bit, here's the big picture:
To map from the Python state to the C state, I think what we want is:
@midhun-pm Does this make sense? I think you're probably more familiar with the C internal details than I am at this point. It does look to me as though the trait internals actually only need one field for this, not two; the idea was presumably originally that there might be other C-level handlers for the post_setattr operation. But changing that is not a change we should make in this PR (and if we did make that change, care would be needed to make sure that we didn't break pickle compatibility). |
Thank you for the explanation ! I was confused by the presence of both fields. It is a lot more clearer to me now and have made the changes that you recommended. |
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. 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.
One tiny nitpick, and please revert the last commit.
This reverts commit c82895b.
Co-Authored-By: Mark Dickinson <mdickinson@enthought.com>
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. Thanks for the updates!
Fix #827
Allow setting CTrait.post_setattr to None