Skip to content
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 KeyError from observe trying to filter events for trait named "*_items" #1328

Merged
merged 6 commits into from
Nov 2, 2020

Conversation

kitchoi
Copy link
Contributor

@kitchoi kitchoi commented Oct 27, 2020

This PR fixes a new bug introduced by #1165 (hence not released).

The first commit adds a test that reveals the issue, it fails with the following error:

Traceback (most recent call last):
  File "/Users/kchoi/Work/ETS/traits/traits/tests/test_observe.py", line 675, in test_observe_event_with_undefined_name_suffix_items
    app.trait_property_changed("i_am_undefined_with_items", 1, 2)
  File "/Users/kchoi/Work/ETS/traits/traits/observation/_trait_event_notifier.py", line 119, in __call__
    if self.prevent_event(event):
  File "/Users/kchoi/Work/ETS/traits/traits/observation/_has_traits_helpers.py", line 132, in ctrait_prevent_event
    ctrait = event.object.traits()[event.name]
KeyError: 'i_am_undefined_with_items'

The second commit fixes it.

Checklist

  • Tests
  • Update API reference (docs/source/traits_api_reference)
  • Update User manual (docs/source/traits_user_manual)
  • Update type annotation hints in traits-stubs

@kitchoi kitchoi changed the title Fix KeyError from filtering event for trait named "*_items" Fix KeyError from observe trying to filter events for trait named "*_items" Oct 27, 2020
Copy link
Member

@mdickinson mdickinson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a couple of questions

@@ -129,8 +129,7 @@ def ctrait_prevent_event(event):
"""
if event.old is Uninitialized:
return True

ctrait = event.object.traits()[event.name]
ctrait = event.object._trait(event.name, 2)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 2 here forces instance trait creation, which seems like a potentially surprising side-effect. Is this necessary? If so, should the docstring be updated to indicate the potential side-effect?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would using the event.object.trait method be an option here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 2 here forces instance trait creation, which seems like a potentially surprising side-effect. Is this necessary?

This function is called when the event has already fired from the CTrait. So persumably the ctrait should have been created already?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyway, yes I can use trait method here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

persumably the ctrait should have been created already

Not sure. Could there be a class trait but not an instance trait at this point? Or are we sure that there already has to be an instance trait?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know - I was asking mainly for my understanding. I had the understanding that change handlers are always attached to an instance CTrait, I don't know if that is right.

Copy link
Member

@mdickinson mdickinson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@@ -129,8 +129,7 @@ def ctrait_prevent_event(event):
"""
if event.old is Uninitialized:
return True

ctrait = event.object.traits()[event.name]
ctrait = event.object.trait(event.name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just as a highly personal nitpicky matter of style, I do like the blank line following the early return.

Copy link
Contributor Author

@kitchoi kitchoi Nov 2, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was accidental, but then I was lazy to revert, sorry about that... reverting.

@kitchoi kitchoi merged commit 1e666fd into master Nov 2, 2020
@kitchoi kitchoi deleted the fix-event-for-undefined-items-trait branch November 2, 2020 16:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants