Failure to install extension dependency does not lead to overall install failure

I used today’s nightly to install SlicerIDCBrowser extension. When trying to load DICOM segmentations I downloaded from IDC using that extension, I realized that QuantitativeReporting extension, which is its dependency, is not installed (the underlying issue is being tracked here, if anyone is interested: https://github.com/Slicer/ExtensionsIndex/issues/2041#issuecomment-2075485309).

Is this the correct behavior? I would expect the installation of an extension to fail if any of its dependencies are not available.

Often not all features of all modules requires all dependencies, so Slicer lets the user refuse installation of certain extensions and the user can also uninstall any extensions at any time.

If Slicer can start the module - even though there are some missing dependencies, which is often the case for Python scripted modules - then the module will be started. It is the responsibility of module developers to check if required modules are available for a certain function and display a meaningful message if they are not. It can be something very simple like this:

I see. I have to say that I do not necessarily agree this is a good approach. In many (most?) other situations (e.g., python packages) dependency (at least usually) means “it will not work if dependency is not satisfied”. I’ve developed a number of extensions, and I had no idea “dependency” has a different semantics in Slicer.

But thank you for the explanation, I should update my modules to deal with this.

In my opinion, if Slicer decided to adopt an unorthodox definition of “dependency”, it would be a lot more useful and intuitive, and a lot less error-prone if the developer could specify in the extension definition file whether dependency is mandatory or not. Otherwise this generic feature you described has to be discovered by every developer and re-implemented in every extension.

Can you clarify - this will prevent the extension from being installed, or it will prevent it from being started?

I want to make sure my extension is not installed if the dependencies are not available.

This just-in-time installation and requirement checking (for both Slicer extensions and Python packages) is indeed more work for developers but allows much more efficiency and better user experience.

Can you clarify - this will prevent the extension from being installed, or it will prevent it from being started?

If you click on the link then you can see those two lines in context. If you put it in your module widget initialization step then you can prevent the module from showing up without the dependency. If you only need a module for a specific feature then you can display the message to the user to let him know that this feature is not available until that extension is installed.

@lassoan Does this mean that the SegmentEditorExtraEffects extension should not be defining a build_dependency of MarkupsToModel because only 2 effects (DrawTube and SurfaceCut) require MarkupsToModel while other effects such as LocalThreshold does not? Where upon attempting to use the DrawTube and SurfaceCut effect without the MarkupsToModel extension installed should at that time warn about that extension needing to be installed to use those effects?

MarkupsToModel is a build dependency if we want to test as part of the build process. But it is true that it is not a strict runtime dependency, because there are many effects that do not require MarkupsToModel extension. And you are right, it would be nicer to show a descriptive error message to the user when MarkupsToModel modules are not available - instead of just logging errors in the application log.

@lassoan I did open the link before asking the earlier question. I wanted to confirm there is no mechanism that will try that function at the time extension is being installed.

The example you provided in your snippet is rather different from my situation.

SlicerHeart does not declare volumereslicedriver as a dependency in the former s4ext file (what is now called build_dependency): ExtensionsIndex/SlicerHeart.json at main · Slicer/ExtensionsIndex · GitHub. SlicerIDCIndex does declare QuantitativeReporting extension as such: ExtensionsIndex/IDCBrowser.json at main · Slicer/ExtensionsIndex · GitHub.

I would expect that my extensions that have dependencies declared in s4ext/json as such missing, should not be installed at all. If those dependencies are missing, I do not want my extension that depends on them to appear at all in the list of modules. I want the install step to fail. @rkikinis ran into this situation just today, and was confused the same way as me.

But I think this issue may be related to a recent regression that @jcfr submitted a fix today: COMP: Fix extension build ensuring build dependency directories are passed by jcfr · Pull Request #7712 · Slicer/Slicer · GitHub. I think what should have happened is that IDCBrowser build should have failed, and it should not have appeared in ExtensionsManager at all. Still, if for any reason extensions in the build_dependency list are missing in ExtensionManager, I believe install should fail.

Soft runtime dependency is a very useful feature, but I agree that it could be useful to add hard runtime dependency, too.

If a dependency is not found during installation of an extension then an error message should be displayed. If no error is displayed then it is a bug. Maybe it was displayed for a couple of seconds, but since the extension was still installed, it may have been easy to overlook.

Still, the dependencies may change, break, modules may be removed or renamed in the dependency, individual modules may be disabled, etc. so whenever a module relies on other module then it makes sense to display a meaningful error message is an expected module or feature is unavailable.