I created a python project, using Pycharm if it matters, that looks like this:
outer_dir/
outside_main.py
module_example/
module_main.py
tests/
test_1.py
…
level_1/
foo_1.py
level_2/
foo_2.py
main.py
calls functions from foo_1.py
foo_1.py
calls functions from foo_2.py
The general use case I'm trying to emulate is a python "package" or repo called module_example
that has been downloaded and used by outside_main.py
at the same level as the top-level package directory.
Here's how module_main.py looks:
# module_main.py
from level_1.foo_1 import foo_function_1
from level_1.level_2.foo_2 import foo_function_2
def main():
print(foo_1())
print(foo_2())
if __name__ == "__main__":
main()
And I can call this top level script from test_1.py
just fine like this:
# test_1.py
from module_main import main
if __name__ == "__main__":
main()
However, when I try to use main() from outside the module_example
directory, with code like this:
# outside_main.py
from module_example.module_main import main
if __name__ == "__main__":
main()
I get this error:
Traceback (most recent call last):
File "/path/to/outside_main.py", line 1, in <module>
from module_example.module_main import main
File "/path/to/module_example/module_main.py", line 1, in <module>
from level_1.foo_1 import foo_function_1
ModuleNotFoundError: No module named 'level_1'
What seems to be happening is that regardless of directory of the python script being imported, its own imports are being searched for relative to the directory from which the main script is executed.
I'm looking for a method of importing that works equally whether I'm calling outside_main.py
or test_1.py
, and regardless of what directory the terminal is currently pointing at.
I've read this post about how python imports work, and it basically suggests I'm out of luck, but that makes no sense to me, all I'm trying to do is emulate using someone's open source library from github, they usually have a tests
folder within their repo, that works fine, but also I can just unzip the entire repo in my project and call import on their py files without issue. How do they do it?
Before entering the hell of sys.path
-patching, I would suggest to wrap your code that currently lives in module_example
into a package_example
directory, add a setup.py
and throw a number of __init__.py
in.
Make package_example
a git repo.
In every other project where you want to use module_example.[...]
, you create a venv
and pip -e /path/to/package_example
.
outer_dir/
outside_main.py
package_example/
.git/
...
setup.py
module_example/
__init__.py
module_main.py
tests/
...
where __init__.py
(one in each subdirectory that contains modules that are to be imported) can just be empty files and setup.py
has to be filled according to the distutils documentation.