Hi everyone,I just wanted to share the attached code. It is an init script that can be used to load modules on-demand, e.g. from a remote location. To use it, you just have to create a "library.zip" with cx_Freeze. The files in this zip file can then be put anywhere, say, an internet server. The init script does not implement this functionality but it shows how it could easily be done by subclassing the class AbstractBlobImporter.
Regards, Markus
#------------------------------------------------------------------------------ # # Init script for cx_Freeze with custom importer # # Written by Markus Meyer <meyer at mesw dot de> # # Note: This method ONLY works if you specify the --append-script-to-exe # option to cx_Freeze. This way, both the init script AND the main # script of your application are appended to the executable. If you # don't use this option, both the init script AND the main script of # your application are put into "library.zip", but this will fail on # runtime because the base executable does not know our custom import # mechanics. If you specify, the --append-script-to-exe option, you make # sure that the base executable can load the init script. From here, you # can do anything you want. # # This script is derived from: # # Console.py # Initialization script for cx_Freeze which manipulates the path so that the # directory in which the executable is found is searched for extensions but # no other directory is searched. It also sets the attribute sys.frozen so that # the Win32 extensions behave as expected. #------------------------------------------------------------------------------ import encodings import os import imp import sys import marshal import warnings import zipfile class AbstractBlobImporter: """ This is the base class for all blob importers. A blob importer is an importer for Python's sys.meta_path facility which can load binary code objects ('blobs') over a defined protocol. Think 'zipimport', but not only for ZIP files, but also for RAR files, FTP connections etc. See the class ZipFileBlobImporter for an example which reimplements zipimport using AbstractBlobImporter importer. """ def find_module(self, fullname, path=None): """ Implement find_module() importer function See PEP 302 for details """ if self._get_path(fullname) is None: return None else: return self def load_module(self, fullname): """ Implement load_module() importer function See PEP 302 for details """ ispkg, code = self._get_code(fullname) mod = sys.modules.setdefault(fullname, imp.new_module(fullname)) mod.__file__ = "<%s>" % self.__class__.__name__ mod.__loader__ = self if ispkg: mod.__path__ = [] # Execute startup code, eventually loading more modules exec code in mod.__dict__ return mod def _get_path(self, fullname): """ Helper function for getting full path and file name where a given module name resides """ # Replace module separator with path separator fullname = fullname.replace(".", "/") for ext in [".pyo", ".pyc"]: # Check if it is a module path = fullname + ext if self.is_blob_available(path): return False, path # Check if it is a package path = fullname + "/__init__" + ext if self.is_blob_available(path): return True, path return None def _get_code(self, fullname): """ Helper function to get Python code object for given module name """ ispkg, path = self._get_path(fullname) s = self.get_blob(path) code_obj = marshal.loads(s[8:]) # strip pyo/pyc file header return ispkg, code_obj def get_blob(self, path): """ This function must be overriden in your subclass. It is given a (relative) path to the pyc/pyo file. You should load the pyc/pyo from this path (the path is "virtual" in that it does not physically need to exist on the file system) and return a Python string which contains the contents of the pyc/pyo file. The given virtual path will always use "/" as the path separator, even on Windows system. """ raise NotImplementedError() def is_blob_available(self, path): """ This function must be overriden in your subclass. It is given a (relative) path to the pyc/pyo file. Return True if this pyc/pyo file exists in your virtual file system, False otherwise. The given virtual path will always use "/" as the path separator, even on Windows system. """ raise NotImplementedError() class ZipFileBlobImporter(AbstractBlobImporter): """ This is a simple class which basically emulates zipimport via subclassing from the blob importer. It loads the code objects from a ZIP file. You can use this class as a starting point for loading the code from any other source. For example, you could load the code objects (*.py[c|o] files) from a RAR file, over the network using a socket connection, from a website etc. """ def __init__(self, filename): self._zip = zipfile.ZipFile(filename, "r") def get_blob(self, path): return self._zip.read(path) def is_blob_available(self, path): return path in self._zip.namelist() # # Add hook for the importer # exe_dir = os.path.abspath(os.path.dirname(sys.argv[0])) sys.meta_path.append( ZipFileBlobImporter(os.path.join(exe_dir, "library.zip"))) # # Remove everything from the path except the executable path # (for loading binary extensions) # sys.path = [exe_dir] # # Bootstrap code (taken from cx_Freeze's Console.py) # sys.frozen = True os.environ["TCL_LIBRARY"] = os.path.join(DIR_NAME, "tcl") os.environ["TK_LIBRARY"] = os.path.join(DIR_NAME, "tk") m = __import__("__main__") import zipimport importer = zipimport.zipimporter(INITSCRIPT_ZIP_FILE_NAME) moduleName = m.__name__ code = importer.get_code(moduleName) exec code in m.__dict__ if sys.version_info[:2] >= (2, 5): module = sys.modules.get("threading") if module is not None: module._shutdown()
------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________ cx-freeze-users mailing list cx-freeze-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/cx-freeze-users