-
Notifications
You must be signed in to change notification settings - Fork 55
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
Disconnect trait change handlers from downstream ApplicationWindow widgets #541
Conversation
And tests are failing on windows because of this... Added |
Codecov Report
@@ Coverage Diff @@
## master #541 +/- ##
==========================================
+ Coverage 36.99% 37.12% +0.13%
==========================================
Files 470 470
Lines 26027 26066 +39
Branches 3961 3964 +3
==========================================
+ Hits 9629 9678 +49
+ Misses 15977 15968 -9
+ Partials 421 420 -1
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.
Thank you for the assessment! Some ideas...
Thank you for the review @kitchoi Following the suggestions I changed the approach:
One concern I have with this is context and temporary menus (e.g. in fields.py) might stick around because of those references, but I've done some testing and I haven't seen any changes in behaviour. I would still labels this as a high risk change as I'm not convinced that it's not going to introduce bugs.
I've implemented a structure similar to the one in |
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.
Thank you very much! This looks pretty reasonable to me. Just some naming nits.
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
Part of #258
Before destroying control of
ApplicationWindow
, trait change handlers from downstream widgets are disconnected.The structure of these underlying widgets and their managers is fairly complex so it's hard to say if it is necessary to disconnect these trait change handlers and if it helps with garbage collection. I attempt to evaluate the risks and the benefits but there might be things that I've missed.
_Menu
inmenu_manager.py
and_ToolBar
intool_bar_manager.py
They connect their methods to Python
MenuManager
andToolBarManager
object traits, but as far as I know that shouldn't prevent any of the objects from being garbage collected. And when either side is deleted, the connection should break. However, if for some reason those connections remain after an attempt to destroy the whole control hierarchy, they might cause problems because there are no safeguards in the handlers.This PR removes
on_trait_change
connections, however, to do so it has to find these objects in the children of the control, since no proper reference is held. The code also only checks that the objects is an instance of expected Qt object, not the custom_Menu
or_ToolBar
because those are private classes. This is risky because there might be otherQMenu
andQToolBar
objects that do not have expecteddisconnect_event_listeners
method. One solution would be to wrap these in atry-except
.I'm open to suggestion on how to better approach this situation and if the potential benefits are worth the risk.
_MenuItem
and_Tool
inaction_item.py
All handlers in
action_item.py
have protectiveif self.control is not None
check so from code inspection it seems that leaving these handlers here shouldn't cause problems. But a disconnect structure was already implemented for_MenuItem
in 8085548, which suggests that not removing the handlers was actually causing problems. Although it was only executed on refresh, not on destruction.This PR connects that structure from
_MenuItem
to the maindestroy
method. The PR doesn't add a similar structure for_Tool
because (1) itsclear
method behaves differently, (2) it would introduce more changes outside of disposal code. Instead trait change handlers of_Tool
are disconnected in a slot that is connected to thedestroyed
signal of its control. I would say that the code added here is low risk because it disconnectson_trait_change
from Python objects. And if the code from the section above doesn't work out, the disconnect in_MenuItem
can also happen in a slot connected todestroyed
signal.There is a qt connection to
_Tool.control.triggered
signal that is not currently disconnected on destruction because there's no good place to do so without adding a lot of extra code. The slot does work with UI components and doesn't have acontrol is None
check so it has some potential of causing problems. But I think a better (lower risk) approach would be to add this check to the slot rather than adding additional structure in order to disconnect it.Note1: There are also 2 qt signal-slot connections that are connected to
destroyed
signal. This PR doesn't disconnect them because they shouldn't be disconnected.Note2:
_PaletteTool
inaction_item.py
hasn't been touched because the support for it has not been implemented in qt.