In a project, I want to dynamically import the right module based on a version-number. For this I'm using importlib, and works find as long as the package is part of the source.
AdminApi = import_module(f"{self.version}", "AdminApi").AdminApi
The folder-structure looks like:
Admin-Package /
- __init__.py # Contains dynamic class loader
- admin64/
- __init__.py # contains AdminApi v6.4
- ...
- admin65/...
- __init__.py # contains AdminApi v6.5
- ...
However, now I find myself needing to decouple the code into its own package to re-use in another project. So I've packaged this part of the source. This however seems to cause path-related issues. This seems to mean that importlib cannot help me.
So far, thanks to: https://stackoverflow.com/a/54138717/5731101 I've come to this point:
import importlib
from pathlib import Path
path = Path(__file__).resolve().parent
script_path = os.path.join(path, version, '__init__.py')
spec = importlib.util.spec_from_file_location(f"AdminApi", script_path)
AdminApi = importlib.util.module_from_spec(spec)
spec.loader.exec_module(AdminApi)
Unfortunately the spec.loader.excec_module
fails with error: ModuleNotFoundError: No module named 'AdminApi'
Even thought the class is clearly available in the file supplied via the path.
I would be grateful if anyone can help me out on this.
I decided to try another tool in the toolbox of importlib Based on this answer: https://stackoverflow.com/a/67692/5731101
from importlib.machinery import SourceFileLoader
foo = SourceFileLoader("AdminAPI", "/path/to/file.py").load_module()
foo.AdminAPI()
This approach had no problems detecting the class and simply imported everything correctly.