-
Notifications
You must be signed in to change notification settings - Fork 2
Lock in QT import dependancy bug + PEP8 Import Compliance #223
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
base: main
Are you sure you want to change the base?
Conversation
…d first to run (though its dependencies still do...)
…` to be loaded first to run.
… loaded first to run.
…licit requirements.py run
…SampleData went is still a mystery)
…time extremely fast!
… until install is complete.
… utility can be re-written
…all; this aligns more closely with PEP standard practice (and defers the import until its actually needed).
|
Haven't gotten any issues yet while testing! Imports all make sense. |
|
Hey @SomeoneInParticular ! When clicking on Load segmentation button and trying to load a previous version, there is an import error (which was not previously present). Can you fix it?
|
…re respect of 08 columns (there are still remaining paragraph of code to consider, however). Please address the comments so this branch can be ready for merge. A bug has been disclosed in the comments. Thanks
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.
Nice work. Interesting to see how much faster SlicerCART is loading!
Left few comments, including some questions.
There is a bug that has been introduced (see comments). Please fix it so it can be ready for PR. Thanks!
| edit_button = qt.QPushButton('Edit') | ||
| edit_button.clicked.connect( | ||
| lambda state, label=label: self.push_edit_button(label)) | ||
| lambda _, l=label: self.push_edit_button(l)) |
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.
Likely a detail, but why did the variable names changed?
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 shorthand for "variable we are not going to use"; this just makes is trivial for Python programmers to "at a glance" understand that they can safely ignore it for debugging purposes.
Likewise, its common for lambda functions to use single-character variables to keep it short. This very much a preference, though; if we prefer to keep "full" variable names, I have no qualms reverting this.
| import slicer | ||
|
|
||
| from importlib import import_module | ||
| from importlib.util import find_spec |
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.
Why find_spec instead of import_module?
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.
find_spec won't import the module into memory, and by extension won't run any initialization code required to import said module. This is part of why SlicerCART boots so much faster now.
Instead, SlicerCART will now only import the package when is first used (so if pandas never gets used, it will never be imported, saving the time it would have taken to do so!)
| Args: | ||
| path: Description of path. | ||
| """ | ||
| from bids_validator import BIDSValidator |
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.
Basic question, but just to make sure I understand it correctly: why this one is only imported here and other imports are done at the beginning? If this module is not installed then Slicer should not fail since BIDSValidator has been pip installed through install_python_packages.py check and install package function?
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.
Good question!
So, this is a "half-way" implementation of how Slicer expects us to handle external dependencies (that is, packages that neither Python nor Slicer provide for us). Their justification for this is detailed here.
The reason this is "half-way" is to avoid having that try-catch check copied in literally every function that calls an external dependency. Instead we instead have it so that it prompts the user to install any missing dependencies during SlicerCART initialization, managed by install_python_packages.py.
This also technically breaks Slicer best practices (specifically this one), but the alternative solutions are likely to introduce even more developer headache:
- Copy-pasting the
try-catchinstall check will bloat the repository, as well as make future development far more tedious. - Wrapping the try-catch in a boilerplate function, which we then import and call, would make IDE development even more painful.
- We could also monkey-patch Python's
importstatement to mediate this for our use; this would preserve IDE compatibility, and save a large amount of boilerplate code. However, its monkey-patching, the joke answer to "how do we solve a problem?"; such a solution would be unstable at best, and risk breaking other Slicer modules if they rely on the default behavior ofimport.
Good catch! Yes, I mistakenly imported the file rather than the class within it; should be fixed with 3cb36e0 |
|
Ok So @SomeoneInParticular is the PR ready to be reviewed again so I can merge it if ok? |
|
Almost @maxradx; just need to run everything through a linter to confirm the "80 characters" test, then should be good to go. WIll do so after my meeting at 2pm. |
|
@SomeoneInParticular ok great! please feel free to advise me when ready! |
# Conflicts resolved: # SlicerCART/src/SlicerCART.py
|
@maxradx Should be ready now! |
|
@SomeoneInParticular I retried again the load segmentation and using your branch I get this: |
|
@maxradx what version of Slicer are you running? I just tested it myself with Slicer 5.8.1, and didn't see the same error. |
|
Update: so, turns out the VTK implementation provided by Slicer simply doesn't provide access to I'm looking into a workaround now, but due to the bug documented in #247, its incredibly difficult to test right now. Will post an update as soon as I can. |
|
@SomeoneInParticular version 5.8.1
It currently works in the main branch, so before merging, it should work. just tried again the steps mentioned above, and it reproduces the error! |
|
So, as it turns out, this was actually an easy fix (though tricky to figure out how to do it). As the loading operation doesn't need to "keep" the old segmentation, we can just modify the prior |
…object, rather than by a function decorator.
|
@maxradx I replaced your @AcastaPaloma give it a spin as well; I think it will help with debugging quite a bit. UPDATE: There was exactly 1 errant leftover use of the function that could crash the program: this has been fixed in 6dcb390 |
…due to being commented out.



As the title suggests, this refactor should fix the need to install anything externally if its provided by 3D Slicer itself. This PR also resolves some poor PEP8 coding practices (namely relying on Python import order to ensure things are imported before we call them) to avoid similar bugs cropping up again in the future.
Next step is digging into how to expose everything to the IDE for development purposes; this will be in a follow-up PR