How can I package a python script and modules into a single script?

Noah noah at noah.org
Wed Nov 23 03:05:42 CET 2005


Alex Martelli wrote:
>
> > This is because zipimport can only import from file paths.
>
> It can import from a file, and the file (like all zipfiles) can have a prefix
> That prefix is where you put the "boot" script.
> See http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/215301

Unfortunately, Raedler's boot script closes stdin, which is a fairly
big limitation.
The herefile in the shell script (END_OF_PYTHON_CODE) redirects stdin
before
python starts; stdin is closed at the end of the herefile. This
disables raw_input()
and anything else that reads sys.stdin. Enter the following at a shell
prompt
to demonstrate the problem:
        python - << HEREFILE
        > print raw_input("Enter something")
        > HEREFILE
You will get the following error:
        Enter somethingTraceback (most recent call last):
          File "<stdin>", line 1, in ?
        EOFError: EOF when reading a line

But all is not lost. The "zipheader.unix" script can be rewritten to
use the '-c' option of python
instead of stdin and a herefile. This also handles the case where
Python may be even less
than version 2.0. This works the same. Just "cat zipheader.unix
main.zip > main" then run "main".

---- 8< ---- 8< ---- save as zipheader.unix ---- 8< ---- 8<
--------------
#!/bin/sh
# This is a self-extracting executable.
# Execute this like any normal executable.
# You may need to "chmod a+x" this file.
# This is a binary ZIP file with a Python loader header.
#
# Bourne shell loader:
PYTHON=$(which python 2>/dev/null)
if [ ! -x "$PYTHON" ] ; then
    echo "Python not found!"
    exit 1
fi
exec $PYTHON -c "
# Python loader:
import sys, os
if int(sys.version[0])<2:
    print 'Python version 2.3 final or greater is required.'
    print 'Your version is', sys.version
    os._exit(1)
major = sys.version_info[0]
minor = sys.version_info[1]
releaselevel = sys.version_info[3]
if (major==2 and minor<3) or (major==2 and minor==3 and
releaselevel!='final'):
    print 'Python version 2.3 final or greater is required.'
    print 'Your version is', sys.version
    os._exit(1)
sys.path.insert(0, sys.argv[1])
del sys.argv[0:1]
print sys.argv[1]
import main
main.main()
" $0 $@

# Zip file:
---- end of zipheader.unix
-----------------------------------------------

Yours,
Noah




More information about the Python-list mailing list