diff --git a/Mac/Lib/py_resource.py b/Mac/Lib/py_resource.py index 3c1343e4f24..85d67e5f589 100644 --- a/Mac/Lib/py_resource.py +++ b/Mac/Lib/py_resource.py @@ -28,9 +28,18 @@ def open(dst): Res.UseResFile(output) return output -def writemodule(name, id, data, type='PYC ', preload=0): +def writemodule(name, id, data, type='PYC ', preload=0, ispackage=0): """Write pyc code to a PYC resource with given name and id.""" # XXXX Check that it doesn't exist + + # Normally, byte 4-7 are the time stamp, but that is not used + # for 'PYC ' resources. We abuse byte 4 as a flag to indicate + # that it is a package rather than an ordinary module. + # See also macimport.c. (jvr) + if ispackage: + data = data[:4] + '\377\0\0\0' + data[8:] # flag resource as package + else: + data = data[:4] + '\0\0\0\0' + data[8:] # clear mod date field, used as package flag res = Res.Resource(data) res.AddResource(type, id, name) if preload: @@ -40,22 +49,23 @@ def writemodule(name, id, data, type='PYC ', preload=0): res.WriteResource() res.ReleaseResource() -def frompycfile(file, name=None, preload=0): +def frompycfile(file, name=None, preload=0, ispackage=0): """Copy one pyc file to the open resource file""" if name == None: d, name = os.path.split(file) name = name[:-4] id = findfreeid() - writemodule(name, id, __builtin__.open(file, 'rb').read(), preload=preload) + data = __builtin__.open(file, 'rb').read() + writemodule(name, id, data, preload=preload, ispackage=ispackage) return id, name -def frompyfile(file, name=None, preload=0): +def frompyfile(file, name=None, preload=0, ispackage=0): """Compile python source file to pyc file and add to resource file""" import py_compile py_compile.compile(file) file = file +'c' - return frompycfile(file, name, preload=preload) + return frompycfile(file, name, preload=preload, ispackage=ispackage) # XXXX Note this is incorrect, it only handles one type and one file.... diff --git a/Mac/Python/macimport.c b/Mac/Python/macimport.c index cf9254378ea..f5f4e209ada 100644 --- a/Mac/Python/macimport.c +++ b/Mac/Python/macimport.c @@ -332,14 +332,45 @@ char *filename; co = NULL; } else { co = PyMarshal_ReadObjectFromString((*h)+8, size-8); + /* + ** Normally, byte 4-7 are the time stamp, but that is not used + ** for 'PYC ' resources. We abuse byte 4 as a flag to indicate + ** that it is a package rather than an ordinary module. + ** See also py_resource.py. (jvr) + */ + if ((*h)[4] & 0xff) { + /* it's a package */ + /* Set __path__ to the package name */ + PyObject *d, *s; + int err; + + m = PyImport_AddModule(module); + if (m == NULL) { + co = NULL; + goto packageerror; + } + d = PyModule_GetDict(m); + s = PyString_InternFromString(module); + if (s == NULL) { + co = NULL; + goto packageerror; + } + err = PyDict_SetItemString(d, "__path__", s); + Py_DECREF(s); + if (err != 0) { + co = NULL; + goto packageerror; + } + } } } +packageerror: HUnlock(h); if ( filerh != -1 ) CloseResFile(filerh); UseResFile(oldrh); if ( co ) { - m = PyImport_ExecCodeModule(module, co); + m = PyImport_ExecCodeModuleEx(module, co, ""); Py_DECREF(co); } else { m = NULL; diff --git a/Mac/Tools/macfreeze/macgen_bin.py b/Mac/Tools/macfreeze/macgen_bin.py index a4ee8289153..e293b63f892 100644 --- a/Mac/Tools/macfreeze/macgen_bin.py +++ b/Mac/Tools/macfreeze/macgen_bin.py @@ -128,10 +128,12 @@ def getfragname(path, dynamicfiles): def addpythonmodules(module_dict): + # XXX should really use macgen_rsrc.generate(), this does the same, but skips __main__ items = module_dict.items() items.sort() for name, module in items: - if module.gettype() != 'module' or name == "__main__": + mtype = module.gettype() + if mtype not in ['module', 'package'] or name == "__main__": continue location = module.__file__ @@ -143,7 +145,8 @@ def addpythonmodules(module_dict): continue print 'Adding module ³%s²' % name - id, name = py_resource.frompyfile(location, name, preload=0) + id, name = py_resource.frompyfile(location, name, preload=0, + ispackage=mtype=='package') def Pstring(str): if len(str) > 255: diff --git a/Mac/Tools/macfreeze/macgen_rsrc.py b/Mac/Tools/macfreeze/macgen_rsrc.py index 107e7346448..2619a6a6d66 100644 --- a/Mac/Tools/macfreeze/macgen_rsrc.py +++ b/Mac/Tools/macfreeze/macgen_rsrc.py @@ -6,9 +6,10 @@ import sys def generate(output, module_dict, debug=0, preload=1): fsid = py_resource.create(output) - + for name, module in module_dict.items(): - if module.gettype() != 'module': + mtype = module.gettype() + if mtype not in ['module', 'package']: continue location = module.__file__ @@ -19,10 +20,11 @@ def generate(output, module_dict, debug=0, preload=1): print '*** skipping', location continue - id, name = py_resource.frompyfile(location, name, preload=preload) + id, name = py_resource.frompyfile(location, name, preload=preload, + ispackage=mtype=='package') if debug > 0: print 'PYC resource %5d\t%s\t%s'%(id, name, location) - + Res.CloseResFile(fsid) def warnings(module_dict):