[XML-SIG] Has anyone frozen scripts that use pyxml with freeze.py on unix ?

Dieter Maurer dieter at handshake.de
Sat May 14 21:29:30 CEST 2005


Joshua M Rhoades wrote at 2005-5-13 16:44 -0700:
>Has anyone frozen scripts that use pyxml with freeze.py on unix ?  I used 
>py2exe for windows but am having difficulty with freeze.py on AIX.
>I'm using python 2.4.1 and pyxml 0.8.4.
>The piece of code currently causing problems is within xpath.
>The problem I am having is with it loading shared object files at run time 
>via a "from" import statement.  In particular, xml/utils/boolean.so.

I solved a similar problem for Zope with a "meta_path" import hook.

In my case, a shared object for a module identified by "<full_module_path>"
as the filename "<full_module_path>.so". I.e. "xml.utils.boolean"
would be in file "xml.utils.boolean.so".

Then I use the followining code to define and install
the "meta_path" hook loading such shared objects.


import sys, imp
from os import environ
from os.path import sep, pathsep
from glob import glob
# note some imports may be missing

if sys.platform == 'win32':
    _SHARED_OBJECT_DESCRIPTION = ('.pyd', 'rb', 3)
else:
    # ATT: not sure whether Win98 uses "win32" as platform
    _SHARED_OBJECT_DESCRIPTION = ('.so', 'rb', 3)
_SHARED_OBJECT_SUFFIX = _SHARED_OBJECT_DESCRIPTION[0]

PATH = environ.get('PYPACKAGE_PATH') or None
if PATH is not None:
    PATH = PATH.split(pathsep)


class _SharedObjectImporter:
    '''singleton to load shared objects for use as a 'meta_hook'.'''
    def __init__(self, path):
        map = {}
        cpath = path[:]; cpath.reverse()
        for p in cpath:
            prefix = p and p + sep or ''
            for fn in glob(prefix + '*' + _SHARED_OBJECT_SUFFIX):
                modname = fn[len(prefix):-len(_SHARED_OBJECT_SUFFIX)]
                map[modname] = fn
                if modname.endswith('module'):
                    map[modname[:-6]] = fn
        self._map = map

    def find_module(self, fullname, unused):
        if fullname in self._map: return self

    def load_module(self, fullname):
        return _load(fullname, self._map[fullname])

def _load(fullname, filename):
    if fullname in sys.modules: return sys.modules[fullname]
    # This whole mess is necessary because Python determines
    #   the package context from the frame that called
    #   "imp.load_module" rather than the full name!
    # ATT: we potentially leave a restricted environment!
    desc = _SHARED_OBJECT_DESCRIPTION
    load = imp.load_module
    if '.' in fullname:
        parent = fullname[:fullname.rindex('.')]
        __import__(parent)
        glbs = sys.modules[parent].__dict__
    else: glbs = {'__builtins__' : __builtins__}
    exec 'load(fullname, None, filename, desc)' in glbs, locals()
    return sys.modules[fullname]

if PATH: sys.meta_path.insert(0, _SharedObjectImporter(PATH))


-- 
Dieter


More information about the XML-SIG mailing list