I recently started working on an existing project.
This project is composed of several git repositories that may use each other in some hierarchy. All repositories should be cloned to the same root directory.
Here's an example of the structure:
root_dir:
repo_a:
module1:
- a.py
- b.py
repo_b:
module1:
- c.py
- d.py
repo_c:
module1:
- e.py
- f.py
Note that I've written "module1" three times on purpose, as it really is the same name.
Now for an example of a file, let's say a.py:
from module1.b import foo
from module1.d import goo
from module1.f import zoo
def func():
foo()
goo()
zoo()
When trying to run it from the root_dir I'm having trouble, I guess due to the ambiguities and not having relative paths.
Is there a way I can run this project properly without internally changing the code?
CodePudding user response:
Based on the boundary having to stick with the given structure using importlib would only need a change in the calls of the imported functions (e.g. foo()
-> repo_a_module1.foo()
) if that's ok for your case.
import importlib.util
repo_a = importlib.util.spec_from_file_location(
"module1", "/repo_a/module1.py")
repo_a_module1 = importlib.util.module_from_spec(repo_a)
repo_a.loader.exec_module(repo_a_module1)
repo_b = importlib.util.spec_from_file_location(
"module1", "/repo_b/module1.py")
repo_b_module1 = importlib.util.module_from_spec(repo_b)
repo_b.loader.exec_module(repo_b_module1)
repo_c = importlib.util.spec_from_file_location(
"module1", "/repo_c/module1.py")
repo_c_module1 = importlib.util.module_from_spec(repo_c)
repo_c.loader.exec_module(repo_c_module1)
repo_a_module1.foo()
repo_b_module1.goo()
repo_c_module1.zoo()
Note: the paths (e.g. "/repo_a/module1.py") have to be changed acc. your filesystem
CodePudding user response:
Another way compared to my previous answer that has less code but the same change in the calls required (e.g. foo()
-> repo_a_module1.foo()
). Again using importlib.
from importlib.machinery import SourceFileLoader
repo_a_module1 = SourceFileLoader("module1",">YourSystemPath</repo_a/module1.py").load_module()
repo_b_module1 = SourceFileLoader("module1",">YourSystemPath</repo_b/module1.py").load_module()
repo_c_module1 = SourceFileLoader("module1",">YourSystemPath</repo_c/module1.py").load_module()
repo_a_module1.foo()
repo_b_module1.goo()
repo_c_module1.zoo()
Note: >YourSystemPath<
can be absolute or relative.