setuptools install your package in a location which is reachable from python i.e. you can import it:
import project
the problem raise when you do relative imports instead of absolute imports. if your main.py
imports config.py
it works because they live in the same directory. when you move your main.py
to another location like /usr/bin
or another location present in PATH environment variable, python try to import config.py
from sys.path
and not from your package dir. the solution is to use absolute import:
from project import config
now main.py
is "movable".
another solution, which i prefer, is using automatic script creation offered by setuptools.
instead of having your code in a
if __name__ == "__main__":
# here all your beautiful code
statement, put your code in a function (main could be a good name):
def main():
# put your code here
if __name__ == "__main__": # not needed, just in case...
main()
now modify your setup.py
:
setup(
# ...
entry_points = {
"console_scripts": [
# modify script_name with the name you want use from shell
# $ script_name [params]
"script_name": "project.main:main",
],
}
)
that's all. after an install setuptools will create a wrapper script which is callable from shell and that calls your main function. now main.py
can live in your project directory and you don't need anymore to move it in a bin/
directory. note that setuptools automatically puts this script in the bin/
directory relative to the installation prefix.
es.
python setup.py install --prefix ~/.local
install your project package in
~/.local/lib/python<version>/site-packages/<package_name>
and your script in
~/.local/bin/<script_name>
so be sure that ~/.local/bin
is present in your PATH env.
more info at: http://peak.telecommunity.com/DevCenter/setuptools#automatic-script-creation