Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 535ffa2

Browse files
committed
added Thomas H's LOADER code for importing extension (sub)modules; little tweaks
1 parent 8e30bcd commit 535ffa2

1 file changed

Lines changed: 27 additions & 21 deletions

File tree

Mac/Lib/bundlebuilder.py

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ def build(self):
141141
self._copyFiles()
142142
self._addMetaFiles()
143143
self.postProcess()
144+
self.message("Done.", 1)
144145

145146
def preProcess(self):
146147
"""Hook for subclasses."""
@@ -200,7 +201,6 @@ def report(self):
200201
pass
201202

202203

203-
204204
if __debug__:
205205
PYC_EXT = ".pyc"
206206
else:
@@ -228,6 +228,13 @@ def report(self):
228228

229229
SITE_CO = compile(SITE_PY, "<-bundlebuilder.py->", "exec")
230230

231+
EXT_LOADER = """\
232+
import imp, sys, os
233+
path = os.path.join(sys.path[0], "%(filename)s")
234+
mod = imp.load_dynamic("%(name)s", path)
235+
sys.modules["%(name)s"] = mod
236+
"""
237+
231238
MAYMISS_MODULES = ['mac', 'os2', 'nt', 'ntpath', 'dos', 'dospath',
232239
'win32api', 'ce', '_winreg', 'nturl2path', 'sitecustomize',
233240
'org.python.core', 'riscos', 'riscosenviron', 'riscospath'
@@ -285,9 +292,6 @@ class AppBuilder(BundleBuilder):
285292
# Strip binaries.
286293
strip = 0
287294

288-
# Found C extension modules: [(name, path), ...]
289-
extensions = []
290-
291295
# Found Python modules: [(name, codeobject, ispkg), ...]
292296
pymodules = []
293297

@@ -355,7 +359,7 @@ def preProcess(self):
355359
mainwrapperpath = pathjoin(execdir, self.name)
356360
makedirs(execdir)
357361
open(mainwrapperpath, "w").write(BOOTSTRAP_SCRIPT % locals())
358-
os.chmod(mainwrapperpath, 0777)
362+
os.chmod(mainwrapperpath, 0775)
359363

360364
def postProcess(self):
361365
self.addPythonModules()
@@ -374,35 +378,35 @@ def postProcess(self):
374378

375379
def addPythonModules(self):
376380
self.message("Adding Python modules", 1)
377-
pymodules = self.pymodules
378381

379382
if USE_FROZEN:
380383
# This anticipates the acceptance of this patch:
381384
# http://www.python.org/sf/642578
382385
# Create a file containing all modules, frozen.
383386
frozenmodules = []
384-
for name, code, ispkg in pymodules:
387+
for name, code, ispkg in self.pymodules:
385388
if ispkg:
386389
self.message("Adding Python package %s" % name, 2)
387390
else:
388391
self.message("Adding Python module %s" % name, 2)
389392
frozenmodules.append((name, marshal.dumps(code), ispkg))
390393
frozenmodules = tuple(frozenmodules)
391-
relpath = "Contents/Resources/" + FROZEN_ARCHIVE
394+
relpath = pathjoin("Contents", "Resources", FROZEN_ARCHIVE)
392395
abspath = pathjoin(self.bundlepath, relpath)
393396
f = open(abspath, "wb")
394397
marshal.dump(frozenmodules, f)
395398
f.close()
396399
# add site.pyc
397-
sitepath = pathjoin(self.bundlepath, "Contents/Resources/site" + PYC_EXT)
400+
sitepath = pathjoin(self.bundlepath, "Contents", "Resources",
401+
"site" + PYC_EXT)
398402
writePyc(SITE_CO, sitepath)
399403
else:
400404
# Create individual .pyc files.
401-
for name, code, ispkg in pymodules:
405+
for name, code, ispkg in self.pymodules:
402406
if ispkg:
403407
name += ".__init__"
404408
path = name.split(".")
405-
path = pathjoin("Contents/Resources/", *path) + PYC_EXT
409+
path = pathjoin("Contents", "Resources", *path) + PYC_EXT
406410

407411
if ispkg:
408412
self.message("Adding Python package %s" % path, 2)
@@ -443,26 +447,28 @@ def findDependencies(self):
443447
except ImportError:
444448
self.missingModules.append(name)
445449

446-
447450
mf.run_script(self.mainprogram)
448451
modules = mf.modules.items()
449452
modules.sort()
450453
for name, mod in modules:
451454
if mod.__file__ and mod.__code__ is None:
452455
# C extension
453456
path = mod.__file__
454-
ext = os.path.splitext(path)[1]
455-
if USE_FROZEN: # "proper" freezing
456-
# rename extensions that are submodules of packages to
457-
# <packagename>.<modulename>.<ext>
458-
dstpath = "Contents/Resources/" + name + ext
457+
filename = os.path.basename(path)
458+
if USE_FROZEN:
459+
# "proper" freezing, put extensions in Contents/Resources/,
460+
# freeze a tiny "loader" program. Due to Thomas Heller.
461+
dstpath = pathjoin("Contents", "Resources", filename)
462+
source = EXT_LOADER % {"name": name, "filename": filename}
463+
code = compile(source, "<dynloader for %s>" % name, "exec")
464+
mod.__code__ = code
459465
else:
460-
dstpath = name.split(".")
461-
dstpath = pathjoin("Contents/Resources/", *dstpath) + ext
466+
# just copy the file
467+
dstpath = name.split(".")[:-1] + [filename]
468+
dstpath = pathjoin("Contents", "Resources", *dstpath)
462469
self.files.append((path, dstpath))
463-
self.extensions.append((name, path, dstpath))
464470
self.binaries.append(dstpath)
465-
elif mod.__code__ is not None:
471+
if mod.__code__ is not None:
466472
ispkg = mod.__path__ is not None
467473
if not USE_FROZEN or name != "site":
468474
# Our site.py is doing the bootstrapping, so we must

0 commit comments

Comments
 (0)