A workaround for the Python module search path issue on Unix
One of the little challenges with writing Unix programs in Python is
the search path problem. The natural structure of Python programs is to
split functionality up into a bunch of modules and then
all in the main program, but the natural structure of a Unix program is
to put its binary into one directory (such as
/usr/bin) but all of
its helper bits into a second, completely different directory. So the
problem is: how is a Unix Python program supposed to find its modules?
(The normal Python search path for
import is the directory that the
program is being run from, such as
$HOME/bin, and the
system Python package areas.)
The obvious solution is to have your program start off by adding its
module directory to
sys.path. The problem here is that this is an
installation dependent location, which means that you're customizing
your main program each time it gets installed. I dislike this and find
it ugly, plus I maintain that overriding
sys.path gets in the way of a
number of things and can cause subtle problems.
It turns out that there is a simple workaround, hinted at by the aside there: put the Python main program into its library directory along with the rest of its modules, and turn the command that gets installed into the binary directory into a tiny shell script that is just:
exec /where/ever/prog.py "$@"
This results in the library directory being added to the search path, because it is the directory that the actual Python program is being run from. (And you can be confidant that Python will know what that is, since the program is being started by absolute path.)
It is easy to create this tiny shell script as part of your installation
process (when you're sure to know where the library directory is, since
you are about to put things in it). As a bonus, your main program can
still have a
.py extension so that you can easily do things like check
it with pychecker or
into an interpreter to poke at something.
(Credit where credit is due: I didn't invent this trick. I believe I first saw it being used by a Python program on Fedora or one of the pre-Fedora Red Hat version.)