Consider the following Python project skeleton:
proj/
├── foo
│ └── __init__.py
├── README.md
└── scripts
└── run.py
In this case f
There's two ways you could resolve this.
Add a proj/setup.py
file with the following contents:
import setuptools
setuptools.setup(
name="my-project",
version="1.0.0",
author="You",
author_email="you@example.com",
description="This is my project",
packages=["foo"],
)
create a virtualenv:
python3 -m venv virtualenv # this creates a directory "virtualenv" in your project
source ./virtualenv/bin/activate # this switches you into the new environment
python setup.py develop # this places your "foo" package in the environment
inside the virtualenv, foo
behaves as an installed package and is importable via import foo
.
So you can use absolute imports in your scripts.
To make them run from anywhere, without needing to activate the virtualenv, you can then specify the path as a shebang.
In scripts/run.py
(the first line is important):
#!/path/to/proj/virtualenv/bin/python
import foo
print(foo.callfunc())
foo
packageInstead of a separate subdirectory scripts
, make a subpackage. In proj/foo/commands/run.py
:
from .. import callfunc()
def main():
print(callfunc())
if __name__ == "__main__":
main()
Then execute the script from the top-level proj/
directory with:
python -m foo.commands.run
If you combine this with (1) and install your package, you can then run python -m foo.commands.run
from anywhere.