mirror of
https://github.com/kennethreitz-archive/pyinstaller.git
synced 2026-06-05 23:50:17 +00:00
implemented zipimport
git-svn-id: http://svn.pyinstaller.org/trunk@475 8dd32b29-ccff-0310-8a9a-9233e24343b1
This commit is contained in:
@@ -126,6 +126,7 @@ class Analysis(Target):
|
||||
self.scripts = TOC()
|
||||
self.pure = TOC()
|
||||
self.binaries = TOC()
|
||||
self.zipfiles = TOC()
|
||||
self.__postinit__()
|
||||
def check_guts(self, last_build):
|
||||
outnm = os.path.basename(self.out)
|
||||
@@ -164,6 +165,7 @@ class Analysis(Target):
|
||||
elif mtime(fnm[:-1]) > last_build:
|
||||
print "building because %s changed" % fnm[:-1]
|
||||
return True
|
||||
# todo: add zipfiles
|
||||
for (nm, fnm, typ) in binaries:
|
||||
if mtime(fnm) > last_build:
|
||||
print "building because %s changed" % fnm
|
||||
@@ -207,6 +209,7 @@ class Analysis(Target):
|
||||
# Fills pure, binaries and rthookcs lists to TOC
|
||||
pure = [] # pure python modules
|
||||
binaries = [] # binaries to bundle
|
||||
zipfiles = [] # zipfiles to bundle
|
||||
rthooks = [] # rthooks if needed
|
||||
for modnm, mod in analyzer.modules.items():
|
||||
# FIXME: why can we have a mod == None here?
|
||||
@@ -220,6 +223,9 @@ class Analysis(Target):
|
||||
fnm = mod.__file__
|
||||
if isinstance(mod, mf.ExtensionModule):
|
||||
binaries.append((mod.__name__, fnm, 'EXTENSION'))
|
||||
elif isinstance(mod, mf.PkgInZipModule):
|
||||
zipfiles.append((os.path.basename(str(mod.owner)),
|
||||
str(mod.owner), 'ZIPFILE'))
|
||||
elif modnm == '__main__':
|
||||
pass
|
||||
else:
|
||||
@@ -230,10 +236,12 @@ class Analysis(Target):
|
||||
self.scripts = TOC(scripts)
|
||||
self.pure = TOC(pure)
|
||||
self.binaries = TOC(binaries)
|
||||
self.zipfiles = TOC(zipfiles)
|
||||
try: # read .toc
|
||||
oldstuff = eval(open(self.out, 'r').read())
|
||||
except:
|
||||
oldstuff = None
|
||||
# todo: add zipfiles
|
||||
if oldstuff != (self.inputs, self.pathex, self.hookspath, self.excludes, scripts, pure, binaries):
|
||||
outf = open(self.out, 'w')
|
||||
pprint.pprint(
|
||||
@@ -412,6 +420,7 @@ class PKG(Target):
|
||||
'PKG' : 'a',
|
||||
'DATA': 'x',
|
||||
'BINARY': 'b',
|
||||
'ZIPFILE': 'Z',
|
||||
'EXECUTABLE': 'b'}
|
||||
def __init__(self, toc, name=None, cdict=None, exclude_binaries=0,
|
||||
strip_binaries=0, upx_binaries=0):
|
||||
@@ -607,7 +616,7 @@ class EXE(Target):
|
||||
exe = exe + '_d'
|
||||
return exe
|
||||
def assemble(self):
|
||||
print "building EXE", os.path.basename(self.out)
|
||||
print "building EXE from", os.path.basename(self.out)
|
||||
trash = []
|
||||
outf = open(self.name, 'wb')
|
||||
exe = self._bootloader_postfix('support/loader/run')
|
||||
|
||||
+6
-3
@@ -71,6 +71,8 @@ else:
|
||||
if "-vi" in sys.argv[1:]:
|
||||
_verbose = 1
|
||||
|
||||
class ArchiveReadError(RuntimeError): pass
|
||||
|
||||
class Archive:
|
||||
""" A base class for a repository of python code objects.
|
||||
The extract method is used by imputil.ArchiveImporter
|
||||
@@ -106,10 +108,10 @@ class Archive:
|
||||
"""
|
||||
self.lib.seek(self.start) #default - magic is at start of file
|
||||
if self.lib.read(len(self.MAGIC)) != self.MAGIC:
|
||||
raise RuntimeError, "%s is not a valid %s archive file" \
|
||||
raise ArchiveReadError, "%s is not a valid %s archive file" \
|
||||
% (self.path, self.__class__.__name__)
|
||||
if self.lib.read(len(self.pymagic)) != self.pymagic:
|
||||
raise RuntimeError, "%s has version mismatch to dll" % (self.path)
|
||||
raise ArchiveReadError, "%s has version mismatch to dll" % (self.path)
|
||||
self.lib.read(4)
|
||||
|
||||
def loadtoc(self):
|
||||
@@ -372,7 +374,8 @@ class PYZOwner(iu.Owner):
|
||||
def __init__(self, path):
|
||||
try:
|
||||
self.pyz = ZlibArchive(path)
|
||||
except IOError, e:
|
||||
self.pyz.checkmagic()
|
||||
except (IOError, ArchiveReadError), e:
|
||||
raise iu.OwnerError(e)
|
||||
iu.Owner.__init__(self, path)
|
||||
def getmod(self, nm, newmod=imp.new_module):
|
||||
|
||||
@@ -33,6 +33,12 @@ try:
|
||||
except AttributeError:
|
||||
py_version = (1,5)
|
||||
|
||||
try:
|
||||
# zipimport is supported starting with Python 2.3
|
||||
import zipimport
|
||||
except ImportError:
|
||||
zipimport = None
|
||||
|
||||
#=======================Owners==========================#
|
||||
# An Owner does imports from a particular piece of turf
|
||||
# That is, there's an Owner for each thing on sys.path
|
||||
@@ -118,10 +124,28 @@ class DirOwner(Owner):
|
||||
mod.__co__ = co
|
||||
return mod
|
||||
|
||||
_globalownertypes = [
|
||||
ZipOwner = None
|
||||
if zipimport:
|
||||
class ZipOwner(Owner):
|
||||
def __init__(self, path):
|
||||
try:
|
||||
self.__zip = zipimport.zipimporter(path)
|
||||
except zipimport.ZipImportError, e:
|
||||
raise OwnerError('%s: %s' % (e.message, path))
|
||||
Owner.__init__(self, path)
|
||||
|
||||
def getmod(self, nm, newmod=imp.new_module):
|
||||
try:
|
||||
return self.__zip.load_module(nm)
|
||||
except zipimport.ZipImportError:
|
||||
return None
|
||||
|
||||
# _mountzlib.py will insert archive.PYZOwner in front later
|
||||
_globalownertypes = filter(None, [
|
||||
ZipOwner,
|
||||
DirOwner,
|
||||
Owner,
|
||||
]
|
||||
])
|
||||
|
||||
#===================Import Directors====================================#
|
||||
# ImportDirectors live on the metapath
|
||||
@@ -428,7 +452,7 @@ class ImportManager:
|
||||
self.setThreaded()
|
||||
else:
|
||||
sys.modules[fqname] = None
|
||||
#print "..found %s" % mod
|
||||
#print "..found %s" % mod, 'when looking for', fqname
|
||||
return mod
|
||||
def reloadHook(self, mod):
|
||||
fqnm = mod.__name__
|
||||
|
||||
@@ -15,6 +15,11 @@
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
import sys, string, os, imp, marshal, dircache
|
||||
try:
|
||||
# zipimport is supported starting with Python 2.3
|
||||
import zipimport
|
||||
except ImportError:
|
||||
zipimport = None
|
||||
|
||||
#=======================Owners==========================#
|
||||
# An Owner does imports from a particular piece of turf
|
||||
@@ -137,11 +142,27 @@ class PYZOwner(Owner):
|
||||
return PkgInPYZModule(nm, co, self)
|
||||
return PyModule(nm, self.path, co)
|
||||
|
||||
_globalownertypes = [
|
||||
ZipOwner = None
|
||||
if zipimport:
|
||||
class ZipOwner(Owner):
|
||||
def __init__(self, path):
|
||||
print 'ZipOwner', path
|
||||
self.__zip = zipimport.zipimporter(path)
|
||||
Owner.__init__(self, path)
|
||||
|
||||
def getmod(self, nm):
|
||||
try:
|
||||
co = self.__zip.get_code(nm)
|
||||
return PkgInZipModule(nm, co, self)
|
||||
except zipimport.ZipImportError:
|
||||
return None
|
||||
|
||||
_globalownertypes = filter(None, [
|
||||
DirOwner,
|
||||
ZipOwner,
|
||||
PYZOwner,
|
||||
Owner,
|
||||
]
|
||||
])
|
||||
|
||||
#===================Import Directors====================================#
|
||||
# ImportDirectors live on the metapath
|
||||
@@ -217,7 +238,8 @@ class RegistryImportDirector(ImportDirector):
|
||||
stuff = open(fnm, 'rb').read()
|
||||
co = loadco(stuff[8:])
|
||||
return PyModule(nm, fnm, co)
|
||||
return None
|
||||
return None
|
||||
|
||||
class PathImportDirector(ImportDirector):
|
||||
def __init__(self, pathlist=None, importers=None, ownertypes=None):
|
||||
if pathlist is None:
|
||||
@@ -596,6 +618,17 @@ class PkgInPYZModule(PyModule):
|
||||
mod = self.owner.getmod(self.__name__ + '.' + nm)
|
||||
return mod
|
||||
|
||||
class PkgInZipModule(PyModule):
|
||||
typ = 'ZIPFILE'
|
||||
def __init__(self, nm, co, pyzowner):
|
||||
PyModule.__init__(self, nm, co.co_filename, co)
|
||||
self._ispkg = 0
|
||||
self.__path__ = [ str(pyzowner) ]
|
||||
self.owner = pyzowner
|
||||
def doimport(self, nm):
|
||||
mod = self.owner.getmod(self.__name__ + '.' + nm)
|
||||
return mod
|
||||
|
||||
#======================== Utility ================================#
|
||||
# Scan the code object for imports, __all__ and wierd stuff
|
||||
|
||||
|
||||
+34
-4
@@ -694,6 +694,28 @@ int installZlib(TOC *ptoc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Add a zipfile to sys.path from a toc entry
|
||||
* Return non zero on failure
|
||||
*/
|
||||
int installZipfile(TOC *ptoc)
|
||||
{
|
||||
int rc;
|
||||
char *tmpl = "sys.path.append(r\"%s" SEP "%s\")\n";
|
||||
char *cmd = (char *) malloc(strlen(tmpl) + strlen(f_workpath)
|
||||
+ strlen(ptoc->name)+ 10);
|
||||
sprintf(cmd, tmpl, f_workpath, ptoc->name);
|
||||
/*VS(cmd);*/
|
||||
rc = PI_PyRun_SimpleString(cmd);
|
||||
if (rc != 0)
|
||||
{
|
||||
FATALERROR("Error in command: %s\n", cmd);
|
||||
free(cmd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Install zlibs
|
||||
@@ -704,14 +726,21 @@ int installZlibs()
|
||||
TOC * ptoc;
|
||||
VS("Installing import hooks\n");
|
||||
|
||||
/* Iterate through toc looking for zlibs (type 'z') */
|
||||
/* Iterate through toc looking for zlibs (type 'z') or
|
||||
* zipfiles (type 'Z')
|
||||
*/
|
||||
ptoc = f_tocbuff;
|
||||
while (ptoc < f_tocend) {
|
||||
if (ptoc->typcd == 'z')
|
||||
if (ptoc->typcd == 'z')
|
||||
{
|
||||
VS("%s\n", ptoc->name);
|
||||
installZlib(ptoc);
|
||||
}
|
||||
else if (ptoc->typcd == 'Z')
|
||||
{
|
||||
VS("zipfile: %s\n", ptoc->name);
|
||||
installZipfile(ptoc);
|
||||
}
|
||||
|
||||
ptoc = incrementTocPtr(ptoc);
|
||||
}
|
||||
@@ -855,7 +884,8 @@ int extract2fs(TOC *ptoc)
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* extract all binaries (type 'b') to the filesystem
|
||||
* extract all binaries (type 'b') and zipfiles (type 'Z')
|
||||
* to the filesystem
|
||||
*/
|
||||
int extractBinaries(char **workpath)
|
||||
{
|
||||
@@ -863,7 +893,7 @@ int extractBinaries(char **workpath)
|
||||
workpath[0] = '\0';
|
||||
VS("Extracting binaries\n");
|
||||
while (ptoc < f_tocend) {
|
||||
if (ptoc->typcd == 'b')
|
||||
if (ptoc->typcd == 'b' || ptoc->typcd == 'Z')
|
||||
if (extract2fs(ptoc))
|
||||
return -1;
|
||||
ptoc = incrementTocPtr(ptoc);
|
||||
|
||||
Reference in New Issue
Block a user