-
Notifications
You must be signed in to change notification settings - Fork 30
Description
Python plugin models don't support with external modules. Unlike C plugins which load and compile the entire source when the model is loaded, python plugins only see the model file.
For the 2-Yukawa model we put the TwoYukawa library in the sasmodels source tree so it would work as a builtin model.
To load it as a sasview plugin model we moved two_yukawa.py and the TwoYukawa library into the plugins directory and used the following import trick:
sasmodels/sasmodels/models/two_yukawa.py
Lines 99 to 124 in 0720b0a
| # If you want a customized version of two_yukawa as a plugin (for example, | |
| # because you want to use the high precision polynomial root solver from mpmath) | |
| # you will need to load the customized TwoYukawa library. The following loads it | |
| # from the plugin directory each time the plugin is loaded. You will need copy | |
| # the following into you plugins directory before modifying: | |
| # https://github.com/SasView/sasmodels/tree/master/sasmodels/models/two_yukawa.py | |
| # https://github.com/SasView/sasmodels/tree/master/sasmodels/TwoYukawa | |
| if 0: | |
| import sys | |
| from pathlib import Path | |
| import importlib.util | |
| # Remove existing TwoYukawa from sys.modules to force a reload | |
| remove = [modname for modname in sys.modules if modname.startswith('TwoYukawa.') or modname == 'TwoYukawa'] | |
| for modname in remove: | |
| del sys.modules[modname] | |
| # Load or reload the TwoYukawa package | |
| path = Path(__file__).resolve().parent | |
| spec = importlib.util.spec_from_file_location('TwoYukawa', str(path / 'TwoYukawa' / '__init__.py')) | |
| module = importlib.util.module_from_spec(spec) | |
| spec.loader.exec_module(module) | |
| sys.modules['TwoYukawa'] = module | |
| # Override sasmodels library symbols with the local symbols. | |
| from TwoYukawa.CalTYSk import CalTYSk, K_MIN, Z_MIN, Z_MIN_DIFF |
We could do something similar to C models and explicitly list the python files that are needed.
It is also possible to be to intercept relative imports with an import hook and capture the dependencies implicitly. There is a proof of concept in the bumps code base, though with the hook registration commented out since it is not currently used:
https://github.com/bumps/bumps/blob/392dab1fc814935e0f5d35cb9a72ebce5eb6de41/bumps/fitproblem.py#L817-L841
https://github.com/bumps/bumps/blob/392dab1fc814935e0f5d35cb9a72ebce5eb6de41/bumps/fitproblem.py#L861-L902