This function will package a python script and additional python modules, in either source or compiled form. Either are directly executable by Python 2.7/3.1 or newer.
Uses make-like logic to only rebuild if something is newer than the previous build.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | #####################################
def makeCheck( target, depend ): # version 2010/02/11
try:
targmod = os.stat( target ).st_mtime
if depend is not None:
for ix in depend:
if os.stat( ix ).st_mtime > targmod:
if debug:
print("makeCheck:",
target, targmod,
ix, os.stat( ix ).st_mtime
)
return True
return False
except:
return True
#####################################
def zipScript( dest, main, progs = None, helps = None, compile = False
): # version 2010/02/11
"""main gets renamed to __main__.py in the zip file
progs are a list of programs or modules to be included, source or compiled
helps is a list of helper modules to be included, source or compiled
"""
tozip = []
toremove = []
funnymain = "__main__.py"
if makeCheck( dest, (main,)) \
or makeCheck( dest, progs ) \
or makeCheck( dest, helps ):
# only if it is out of date
import zipfile
zf = zipfile.ZipFile( dest, "w", zipfile.ZIP_DEFLATED )
if compile:
import py_compile
ixc = funnymain + "c"
toremove.append( ixc )
tozip.append( ixc )
py_compile.compile( main, ixc, doraise = True )
for ix in progs:
ixc = ix + "c"
toremove.append( ixc )
tozip.append( ixc )
py_compile.compile( ix, ixc, doraise = True )
for ix in helps:
ixc = ix + "c"
toremove.append( ixc )
tozip.append( ixc )
py_compile.compile( ix, ixc, doraise = True )
else:
for ix in progs:
tozip.append( ix )
for ix in helps:
tozip.append( ix )
zf.write( ix, funnymain )
for ix in tozip:
zf.write( ix )
zf.close()
for ix in toremove:
os.remove( ix )
#####################################
|
Invoke the code with something like:
zipScript("a.py", "src.py", ("depend1.py", "depend2.py"))
This will package source files as a zip, with src.py becoming __main__.py within the zip.
zipScript("a.py", "src.py", ("depend1.py", "depend2.py"), compile=True )
The compile parameter set to True will compile all the packages before placing them in the target zip file. But that adds a dependency on some particular versions of Python that can execute that form of compiled code. If distributing your application, you might need to build multiple version of your zipScript package with multiple versions of Python to reach all customers.
For older versions of Python, see http://code.activestate.com/recipes/497000/
This code :
crashes with the following output :
Changing line 57 from
to
does the trick. Also I think its better to write
than
because the second script raises TypeError :
Thanks, Marcus, for the suggestions/corrections. Somehow they never got emailed to me, but I happened back to look at this recipe, when I created another just now, and found them.