Run a program containing submodules
Assume we have the following layout:
– module_with_sub_module: the directory that contains the application(It is not the base module directory but a directory that holds it ).
– foo/app: a submodule
– foo/business: a submodule
– foo/core: a submodule
And here the main program:
from foo.business.FooClass import FooClass def main(): foo = FooClass() input = 'lion' output: str = foo.do_foo(input) print(f'input={input},output={output}') if __name__ == '__main__': main() |
Type of errors encountered
Error when we execute the application from the root module:
Execute the application in this ways trigger a ModuleNotFoundError:
module_with_sub_module$ python3.9 foo/app/Main.py
Traceback (most recent call last): File "/home/david/python-workspace/python_blog_examples/module_with_sub_module/foo/app/Main.py", line 8, in <module> from foo.business.FooClass import FooClass |
If we print the value of sys.path
, we could see that the base module is not inside it, only the module of the executed program/file is in it:
/home/david/python-workspace/python_blog_examples/module_with_sub_module/foo/app
sys.path=['/home/david/python-workspace/python_blog_examples/module_with_sub_module/foo/app', '/usr/lib/python39.zip', '/usr/lib/python3.9', '/usr/lib/python3.9/lib-dynload', '/home/david/.local/lib/python3.9/site-packages', '/usr/local/lib/python3.9/dist-packages', '/usr/lib/python3/dist-packages'] |
Solution:
Add the working directory, that is also here the project root directory in sys.path
.
You have mainly 2 ways to do that:
– Updating sys.path
before importing any submodules in the main program:
sys.path.append(os.getcwd()) |
If the error persists, you can print the value of sys.path
.
So the main program could look like finally :
import os import sys # PYTHONPATH sys.path.append(os.getcwd()) print(f'after sys.path={sys.path}') from foo.business.FooClass import FooClass def main(): foo = FooClass() input = 'lion' output: str = foo.do_foo(input) print(f'input={input},output={output}') if __name__ == '__main__': main() |
– Updating the PYTHONPATH env variable before launching the program:
export PYTHONPATH=.:${PYTHONPATH}
Error because of missing __init__.py files:
You must add __init__.py
in the submodules where you have the import errors.