From a5568d349bd0a2f4ca427e97f19d237ba4c0925a Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Thu, 5 Mar 1998 03:45:08 +0000 Subject: Support for frozen packages, matching the revamped Tools/freeze. Frozen packages are indicated by a negative size (the code string is the __import__.py file). A frozen package module has its __path__ set to a string, the package name. --- Python/import.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 14 deletions(-) diff --git a/Python/import.c b/Python/import.c index edc960c..6ab1371 100644 --- a/Python/import.c +++ b/Python/import.c @@ -829,18 +829,22 @@ find_module(name, path, buf, buflen, p_fp) FILE **p_fp; { int i, npath, len, namelen; + struct _frozen *f; struct filedescr *fdp = NULL; FILE *fp = NULL; struct stat statbuf; + static struct filedescr fd_frozen = {"", "", PY_FROZEN}; + static struct filedescr fd_builtin = {"", "", C_BUILTIN}; + static struct filedescr fd_package = {"", "", PKG_DIRECTORY}; if (path == NULL) { if (is_builtin(name)) { - static struct filedescr fd = {"", "", C_BUILTIN}; - return &fd; + strcpy(buf, name); + return &fd_builtin; } - if (find_frozen(name) != NULL) { - static struct filedescr fd = {"", "", PY_FROZEN}; - return &fd; + if ((f = find_frozen(name)) != NULL) { + strcpy(buf, name); + return &fd_frozen; } #ifdef MS_COREDLL @@ -850,14 +854,28 @@ find_module(name, path, buf, buflen, p_fp) return fdp; } #endif + path = PySys_GetObject("path"); + } + else if (PyString_Check(path)) { + /* Submodule of frozen package */ + if (PyString_Size(path) + 1 + strlen(name) >= buflen) { + PyErr_SetString(PyExc_ImportError, + "full frozen module name too long"); + return NULL; + } + strcpy(buf, PyString_AsString(path)); + strcat(buf, "."); + strcat(buf, name); + if (find_frozen(buf) != NULL) + return &fd_frozen; + PyErr_Format(PyExc_ImportError, + "frozen module %.200s not found", buf); + return NULL; } - - if (path == NULL) - path = PySys_GetObject("path"); if (path == NULL || !PyList_Check(path)) { PyErr_SetString(PyExc_ImportError, - "sys.path must be a list of directory names"); + "sys.path must be a list of directory names"); return NULL; } npath = PyList_Size(path); @@ -915,7 +933,6 @@ find_module(name, path, buf, buflen, p_fp) } #ifdef HAVE_STAT if (stat(buf, &statbuf) == 0) { - static struct filedescr fd = {"", "", PKG_DIRECTORY}; if (S_ISDIR(statbuf.st_mode)) { if (find_init_module(buf)) { #ifdef CHECK_IMPORT_CASE @@ -923,7 +940,7 @@ find_module(name, path, buf, buflen, p_fp) name)) return NULL; #endif - return &fd; + return &fd_package; } } } @@ -1141,6 +1158,8 @@ load_module(name, fp, buf, type) case C_BUILTIN: case PY_FROZEN: + if (buf != NULL && buf[0] != '\0') + name = buf; if (type == C_BUILTIN) err = init_builtin(name); else @@ -1239,6 +1258,7 @@ get_frozen_object(name) char *name; { struct _frozen *p = find_frozen(name); + int size; if (p == NULL) { PyErr_Format(PyExc_ImportError, @@ -1246,7 +1266,10 @@ get_frozen_object(name) name); return NULL; } - return PyMarshal_ReadObjectFromString((char *)p->code, p->size); + size = p->size; + if (size < 0) + size = -size; + return PyMarshal_ReadObjectFromString((char *)p->code, size); } /* Initialize a frozen module. @@ -1261,12 +1284,19 @@ PyImport_ImportFrozenModule(name) struct _frozen *p = find_frozen(name); PyObject *co; PyObject *m; + int ispackage; + int size; if (p == NULL) return 0; + size = p->size; + ispackage = (size < 0); + if (ispackage) + size = -size; if (Py_VerboseFlag) - fprintf(stderr, "import %s # frozen\n", name); - co = PyMarshal_ReadObjectFromString((char *)p->code, p->size); + fprintf(stderr, "import %s # frozen%s\n", + name, ispackage ? " package" : ""); + co = PyMarshal_ReadObjectFromString((char *)p->code, size); if (co == NULL) return -1; if (!PyCode_Check(co)) { @@ -1276,6 +1306,22 @@ PyImport_ImportFrozenModule(name) name); return -1; } + if (ispackage) { + /* Set __path__ to the package name */ + PyObject *d, *s; + int err; + m = PyImport_AddModule(name); + if (m == NULL) + return -1; + d = PyModule_GetDict(m); + s = PyString_InternFromString(name); + if (s == NULL) + return -1; + err = PyDict_SetItemString(d, "__path__", s); + Py_DECREF(s); + if (err != 0) + return err; + } m = PyImport_ExecCodeModuleEx(name, co, ""); Py_DECREF(co); if (m == NULL) -- cgit v0.12