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
Emit event from Points data setter #6117
Conversation
Codecov Report
@@ Coverage Diff @@
## main #6117 +/- ##
=======================================
Coverage 91.61% 91.62%
=======================================
Files 579 579
Lines 50636 50656 +20
=======================================
+ Hits 46392 46414 +22
+ Misses 4244 4242 -2
|
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 think I found out why I removed the line you mentioned. When testing using this code:
import napari
def test(event):
print(event.data_indices)
print(event.vertex_indices)
print(event.action)
viewer = napari.Viewer()
viewer.add_points()
viewer.layers[0].events.data.connect(test)
napari.run()
if you now start adding points you see that each time there are 2 emits. One coming from the data.setter
which actually gives wrong information. I am not certain why in the shapes layer having the line self.events.data(value=self.data)
in the setter does not gives issues while something similar in Points
does. I will have a look after the break, but at least it seems to be the case that the data setter gets called every time the data is changed.
Ah, that's ok, we've encountered situations like this in the past — the trick is then to create a "set data quietly" private method that all the emitting methods use, and then the setter simply uses that method and then emits. The editing methods are using the setter because NumPy arrays aren't expandable — we could/should optimise that with an expandable array but it's never happened 😅, because NumPy is fast enough when creating an array with a million points anyway! 😅 |
If I understand correctly, the difference with |
34656d8
to
3be54a7
Compare
@melonora here you go, added a regression test and everything. 😊 |
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 think that we should use unittest Mock in tests instead of append on list.
... because? I'm not really sure how Mock would improve things here. As far as I can tell the list tests exactly what it purports to test? |
Thanks @jni! I am happy with the change, but do have one question where I am not certain whether it would be something to change as part of this PR. The data event in the |
@melonora i think that should come in a separate PR. It's good to keep PRs as compact as possible to achieve what they need to do (in this case, fix a bug in the points layer). Maybe make an issue? |
Yeah I agree, I will open an issue and will approve this PR, though lets wait for the response of @Czaki before starting the clock. |
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.
Readability?
Co-authored-by: Grzegorz Bokota <bokota+github@gmail.com>
Thanks for the suggestions. 🙏 As someone who is unfamiliar with Mock but intimately familiar with lists (which I suspect describes many Python users), I actually find this less readable. But I don't feel strongly about it at all. This should be ready! 🚀 |
For me, Mock is more readable, as I do not need to parse connected functions. |
In it goes |
# Fixes/Closes Closes #6125 # Description With #6117 the emitted data in the `data.setter` of `Points` has been made more consistent with the emitted data when adding, changing or removing data within the layer. However, in `Shapes` only the data itself was emitted. Furthermore, since the `data.setter` in Shapes called the public `.add` method and emits data itself, a `layers.data` event was emitted twice. This PR is a slight refactor so that `data.setter` can directly call the private `_add_shapes` method, bypassing the `layer.data` emit in `.add`. ## Type of change - [x] Bug-fix (non-breaking change which fixes an issue) - [x] Maintenance (changes required to run napari, tests, & CI smoothly) # How has this been tested? - [x] example: the test suite for my feature covers cases x, y, and z - [x] example: all tests pass with my change - [x] example: I check if my changes works with both PySide and PyQt backends as there are small differences between the two Qt bindings. ## Final checklist: - [x] My PR is the minimum possible work for the desired functionality - [x] I have added tests that prove my fix is effective or that my feature works - [x] If I included new strings, I have used `trans.` to make them localizable. For more information see our [translations guide](https://napari.org/developers/translations.html).
Closes #6116 # Description Adds back an event emission from the Points layer data setter. Commits summary: - Add failing test for layer data setter event - Emit event on points data setter ## Type of change <!-- Please delete options that are not relevant. --> - [x] Bug-fix (non-breaking change which fixes an issue) --------- Co-authored-by: Grzegorz Bokota <bokota+github@gmail.com>
# Fixes/Closes Closes #6125 # Description With #6117 the emitted data in the `data.setter` of `Points` has been made more consistent with the emitted data when adding, changing or removing data within the layer. However, in `Shapes` only the data itself was emitted. Furthermore, since the `data.setter` in Shapes called the public `.add` method and emits data itself, a `layers.data` event was emitted twice. This PR is a slight refactor so that `data.setter` can directly call the private `_add_shapes` method, bypassing the `layer.data` emit in `.add`. ## Type of change - [x] Bug-fix (non-breaking change which fixes an issue) - [x] Maintenance (changes required to run napari, tests, & CI smoothly) # How has this been tested? - [x] example: the test suite for my feature covers cases x, y, and z - [x] example: all tests pass with my change - [x] example: I check if my changes works with both PySide and PyQt backends as there are small differences between the two Qt bindings. ## Final checklist: - [x] My PR is the minimum possible work for the desired functionality - [x] I have added tests that prove my fix is effective or that my feature works - [x] If I included new strings, I have used `trans.` to make them localizable. For more information see our [translations guide](https://napari.org/developers/translations.html).
Closes #6116
Description
Adds back an event emission from the Points layer data setter. Commits summary:
Type of change