diff options
Diffstat (limited to 'Python/import.c')
| -rw-r--r-- | Python/import.c | 290 |
1 files changed, 159 insertions, 131 deletions
diff --git a/Python/import.c b/Python/import.c index 07f5720..4d8a610 100644 --- a/Python/import.c +++ b/Python/import.c @@ -27,8 +27,6 @@ extern "C" { typedef unsigned short mode_t; #endif -extern time_t PyOS_GetLastModificationTime(char *, FILE *); - /* In getmtime.c */ /* Magic word to reject .pyc files generated by other Python versions. It should change for each incompatible change to the bytecode. @@ -73,9 +71,15 @@ extern time_t PyOS_GetLastModificationTime(char *, FILE *); Python 2.5c2: 62131 (fix wrong code: for x, in ... in listcomp/genexp) Python 2.6a0: 62151 (peephole optimizations and STORE_MAP opcode) Python 2.6a1: 62161 (WITH_CLEANUP optimization) + Python 2.7a0: 62171 (optimize list comprehensions/change LIST_APPEND) + Python 2.7a0: 62181 (optimize conditional branches: + introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE) + Python 2.7a0 62191 (introduce SETUP_WITH) + Python 2.7a0 62201 (introduce BUILD_SET) + Python 2.7a0 62211 (introduce MAP_ADD and SET_ADD) . */ -#define MAGIC (62161 | ((long)'\r'<<16) | ((long)'\n'<<24)) +#define MAGIC (62211 | ((long)'\r'<<16) | ((long)'\n'<<24)) /* Magic word as global; note that _PyImport_Init() can change the value of this global to accommodate for alterations of how the @@ -110,6 +114,34 @@ static const struct filedescr _PyImport_StandardFiletab[] = { }; #endif +#ifdef MS_WINDOWS +int isdir(char *path) { + DWORD rv; + /* see issue1293 and issue3677: + * stat() on Windows doesn't recognise paths like + * "e:\\shared\\" and "\\\\whiterab-c2znlh\\shared" as dirs. + * Also reference issue6727: + * stat() on Windows is broken and doesn't resolve symlinks properly. + */ + rv = GetFileAttributesA(path); + return rv != INVALID_FILE_ATTRIBUTES && rv & FILE_ATTRIBUTE_DIRECTORY; +} +#else +#ifdef HAVE_STAT +int isdir(char *path) { + struct stat statbuf; + return stat(path, &statbuf) == 0 && S_ISDIR(statbuf.st_mode); +} +#else +#ifdef RISCOS +/* with RISCOS, isdir is in unixstuff */ +#else +int isdir(char *path) { + return 0; +} +#endif /* RISCOS */ +#endif /* HAVE_STAT */ +#endif /* MS_WINDOWS */ /* Initialize things */ @@ -619,7 +651,7 @@ PyImport_AddModule(const char *name) /* Remove name from sys.modules, if it's there. */ static void -_RemoveModule(const char *name) +remove_module(const char *name) { PyObject *modules = PyImport_GetModuleDict(); if (PyDict_GetItemString(modules, name) == NULL) @@ -691,7 +723,7 @@ PyImport_ExecCodeModuleEx(char *name, PyObject *co, char *pathname) return m; error: - _RemoveModule(name); + remove_module(name); return NULL; } @@ -901,9 +933,9 @@ write_compiled_module(PyCodeObject *co, char *cpathname, struct stat *srcstat) (void) unlink(cpathname); return; } - /* Now write the true mtime */ + /* Now write the true mtime (as a 32-bit field) */ fseek(fp, 4L, 0); - assert(mtime < LONG_MAX); + assert(mtime <= 0xFFFFFFFF); PyMarshal_WriteLongToFile((long)mtime, fp, Py_MARSHAL_VERSION); fflush(fp); fclose(fp); @@ -964,7 +996,7 @@ load_source_module(char *name, char *pathname, FILE *fp) { struct stat st; FILE *fpc; - char buf[MAXPATHLEN+1]; + char *buf; char *cpathname; PyCodeObject *co; PyObject *m; @@ -975,17 +1007,18 @@ load_source_module(char *name, char *pathname, FILE *fp) pathname); return NULL; } -#if SIZEOF_TIME_T > 4 - /* Python's .pyc timestamp handling presumes that the timestamp fits - in 4 bytes. This will be fine until sometime in the year 2038, - when a 4-byte signed time_t will overflow. - */ - if (st.st_mtime >> 32) { - PyErr_SetString(PyExc_OverflowError, - "modification time overflows a 4 byte field"); - return NULL; + if (sizeof st.st_mtime > 4) { + /* Python's .pyc timestamp handling presumes that the timestamp fits + in 4 bytes. Since the code only does an equality comparison, + ordering is not important and we can safely ignore the higher bits + (collisions are extremely unlikely). + */ + st.st_mtime &= 0xFFFFFFFF; + } + buf = PyMem_MALLOC(MAXPATHLEN+1); + if (buf == NULL) { + return PyErr_NoMemory(); } -#endif cpathname = make_compiled_pathname(pathname, buf, (size_t)MAXPATHLEN + 1); if (cpathname != NULL && @@ -993,9 +1026,9 @@ load_source_module(char *name, char *pathname, FILE *fp) co = read_compiled_module(cpathname, fpc); fclose(fpc); if (co == NULL) - return NULL; + goto error_exit; if (update_compiled_module(co, pathname) < 0) - return NULL; + goto error_exit; if (Py_VerboseFlag) PySys_WriteStderr("import %s # precompiled from %s\n", name, cpathname); @@ -1004,7 +1037,7 @@ load_source_module(char *name, char *pathname, FILE *fp) else { co = parse_source_module(pathname, fp); if (co == NULL) - return NULL; + goto error_exit; if (Py_VerboseFlag) PySys_WriteStderr("import %s # from %s\n", name, pathname); @@ -1017,7 +1050,12 @@ load_source_module(char *name, char *pathname, FILE *fp) m = PyImport_ExecCodeModuleEx(name, (PyObject *)co, pathname); Py_DECREF(co); + PyMem_FREE(buf); return m; + +error_exit: + PyMem_FREE(buf); + return NULL; } @@ -1037,7 +1075,7 @@ load_package(char *name, char *pathname) PyObject *file = NULL; PyObject *path = NULL; int err; - char buf[MAXPATHLEN+1]; + char *buf = NULL; FILE *fp = NULL; struct filedescr *fdp; @@ -1059,8 +1097,13 @@ load_package(char *name, char *pathname) err = PyDict_SetItemString(d, "__path__", path); if (err != 0) goto error; + buf = PyMem_MALLOC(MAXPATHLEN+1); + if (buf == NULL) { + PyErr_NoMemory(); + goto error; + } buf[0] = '\0'; - fdp = find_module(name, "__init__", path, buf, sizeof(buf), &fp, NULL); + fdp = find_module(name, "__init__", path, buf, MAXPATHLEN+1, &fp, NULL); if (fdp == NULL) { if (PyErr_ExceptionMatches(PyExc_ImportError)) { PyErr_Clear(); @@ -1078,6 +1121,8 @@ load_package(char *name, char *pathname) error: m = NULL; cleanup: + if (buf) + PyMem_FREE(buf); Py_XDECREF(path); Py_XDECREF(file); return m; @@ -1203,13 +1248,10 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf, char *filemode; FILE *fp = NULL; PyObject *path_hooks, *path_importer_cache; -#ifndef RISCOS - struct stat statbuf; -#endif static struct filedescr fd_frozen = {"", "", PY_FROZEN}; static struct filedescr fd_builtin = {"", "", C_BUILTIN}; static struct filedescr fd_package = {"", "", PKG_DIRECTORY}; - char name[MAXPATHLEN+1]; + char *name; #if defined(PYOS_OS2) size_t saved_len; size_t saved_namelen; @@ -1223,6 +1265,10 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf, "module name is too long"); return NULL; } + name = PyMem_MALLOC(MAXPATHLEN+1); + if (name == NULL) { + return PyErr_NoMemory(); + } strcpy(name, subname); /* sys.meta_path import hook */ @@ -1231,10 +1277,10 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf, meta_path = PySys_GetObject("meta_path"); if (meta_path == NULL || !PyList_Check(meta_path)) { - PyErr_SetString(PyExc_ImportError, + PyErr_SetString(PyExc_RuntimeError, "sys.meta_path must be a list of " "import hooks"); - return NULL; + goto error_exit; } Py_INCREF(meta_path); /* zap guard */ npath = PyList_Size(meta_path); @@ -1247,12 +1293,13 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf, path : Py_None); if (loader == NULL) { Py_DECREF(meta_path); - return NULL; /* true error */ + goto error_exit; /* true error */ } if (loader != Py_None) { /* a loader was found */ *p_loader = loader; Py_DECREF(meta_path); + PyMem_FREE(name); return &importhookdescr; } Py_DECREF(loader); @@ -1266,7 +1313,7 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf, if (PyString_Size(path) + 1 + strlen(name) >= (size_t)buflen) { PyErr_SetString(PyExc_ImportError, "full frozen module name too long"); - return NULL; + goto error_exit; } strcpy(buf, PyString_AsString(path)); strcat(buf, "."); @@ -1274,19 +1321,22 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf, strcpy(name, buf); if (find_frozen(name) != NULL) { strcpy(buf, name); + PyMem_FREE(name); return &fd_frozen; } PyErr_Format(PyExc_ImportError, "No frozen submodule named %.200s", name); - return NULL; + goto error_exit; } if (path == NULL) { if (is_builtin(name)) { strcpy(buf, name); + PyMem_FREE(name); return &fd_builtin; } if ((find_frozen(name)) != NULL) { strcpy(buf, name); + PyMem_FREE(name); return &fd_frozen; } @@ -1294,30 +1344,31 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf, fp = PyWin_FindRegisteredModule(name, &fdp, buf, buflen); if (fp != NULL) { *p_fp = fp; + PyMem_FREE(name); return fdp; } #endif path = PySys_GetObject("path"); } if (path == NULL || !PyList_Check(path)) { - PyErr_SetString(PyExc_ImportError, + PyErr_SetString(PyExc_RuntimeError, "sys.path must be a list of directory names"); - return NULL; + goto error_exit; } path_hooks = PySys_GetObject("path_hooks"); if (path_hooks == NULL || !PyList_Check(path_hooks)) { - PyErr_SetString(PyExc_ImportError, + PyErr_SetString(PyExc_RuntimeError, "sys.path_hooks must be a list of " "import hooks"); - return NULL; + goto error_exit; } path_importer_cache = PySys_GetObject("path_importer_cache"); if (path_importer_cache == NULL || !PyDict_Check(path_importer_cache)) { - PyErr_SetString(PyExc_ImportError, + PyErr_SetString(PyExc_RuntimeError, "sys.path_importer_cache must be a dict"); - return NULL; + goto error_exit; } npath = PyList_Size(path); @@ -1326,13 +1377,13 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf, PyObject *copy = NULL; PyObject *v = PyList_GetItem(path, i); if (!v) - return NULL; + goto error_exit; #ifdef Py_USING_UNICODE if (PyUnicode_Check(v)) { copy = PyUnicode_Encode(PyUnicode_AS_UNICODE(v), PyUnicode_GET_SIZE(v), Py_FileSystemDefaultEncoding, NULL); if (copy == NULL) - return NULL; + goto error_exit; v = copy; } else @@ -1358,7 +1409,7 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf, path_hooks, v); if (importer == NULL) { Py_XDECREF(copy); - return NULL; + goto error_exit; } /* Note: importer is a borrowed reference */ if (importer != Py_None) { @@ -1368,10 +1419,11 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf, "s", fullname); Py_XDECREF(copy); if (loader == NULL) - return NULL; /* error */ + goto error_exit; /* error */ if (loader != Py_None) { /* a loader was found */ *p_loader = loader; + PyMem_FREE(name); return &importhookdescr; } Py_DECREF(loader); @@ -1391,12 +1443,11 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf, /* Check for package import (buf holds a directory name, and there's an __init__ module in that directory */ -#ifdef HAVE_STAT - if (stat(buf, &statbuf) == 0 && /* it exists */ - S_ISDIR(statbuf.st_mode) && /* it's a directory */ + if (isdir(buf) && /* it's an existing directory */ case_ok(buf, len, namelen, name)) { /* case matches */ if (find_init_module(buf)) { /* and has __init__.py */ Py_XDECREF(copy); + PyMem_FREE(name); return &fd_package; } else { @@ -1407,32 +1458,10 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf, if (PyErr_Warn(PyExc_ImportWarning, warnstr)) { Py_XDECREF(copy); - return NULL; + goto error_exit; } } } -#else - /* XXX How are you going to test for directories? */ -#ifdef RISCOS - if (isdir(buf) && - case_ok(buf, len, namelen, name)) { - if (find_init_module(buf)) { - Py_XDECREF(copy); - return &fd_package; - } - else { - char warnstr[MAXPATHLEN+80]; - sprintf(warnstr, "Not importing directory " - "'%.*s': missing __init__.py", - MAXPATHLEN, buf); - if (PyErr_Warn(PyExc_ImportWarning, - warnstr)) { - Py_XDECREF(copy); - return NULL; - } - } -#endif -#endif #if defined(PYOS_OS2) /* take a snapshot of the module spec for restoration * after the 8 character DLL hackery @@ -1504,10 +1533,15 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf, if (fp == NULL) { PyErr_Format(PyExc_ImportError, "No module named %.200s", name); - return NULL; + goto error_exit; } *p_fp = fp; + PyMem_FREE(name); return fdp; + +error_exit: + PyMem_FREE(name); + return NULL; } /* Helpers for main.c @@ -1797,7 +1831,7 @@ static int init_builtin(char *); /* Forward */ its module object WITH INCREMENTED REFERENCE COUNT */ static PyObject * -load_module(char *name, FILE *fp, char *buf, int type, PyObject *loader) +load_module(char *name, FILE *fp, char *pathname, int type, PyObject *loader) { PyObject *modules; PyObject *m; @@ -1818,27 +1852,27 @@ load_module(char *name, FILE *fp, char *buf, int type, PyObject *loader) switch (type) { case PY_SOURCE: - m = load_source_module(name, buf, fp); + m = load_source_module(name, pathname, fp); break; case PY_COMPILED: - m = load_compiled_module(name, buf, fp); + m = load_compiled_module(name, pathname, fp); break; #ifdef HAVE_DYNAMIC_LOADING case C_EXTENSION: - m = _PyImport_LoadDynamicModule(name, buf, fp); + m = _PyImport_LoadDynamicModule(name, pathname, fp); break; #endif case PKG_DIRECTORY: - m = load_package(name, buf); + m = load_package(name, pathname); break; case C_BUILTIN: case PY_FROZEN: - if (buf != NULL && buf[0] != '\0') - name = buf; + if (pathname != NULL && pathname[0] != '\0') + name = pathname; if (type == C_BUILTIN) err = init_builtin(name); else @@ -2060,7 +2094,9 @@ PyImport_ImportModuleNoBlock(const char *name) { PyObject *result; PyObject *modules; +#ifdef WITH_THREAD long me; +#endif /* Try to get the module from sys.modules[name] */ modules = PyImport_GetModuleDict(); @@ -2112,7 +2148,7 @@ static PyObject * import_module_level(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level) { - char buf[MAXPATHLEN+1]; + char *buf; Py_ssize_t buflen = 0; PyObject *parent, *head, *next, *tail; @@ -2126,14 +2162,18 @@ import_module_level(char *name, PyObject *globals, PyObject *locals, return NULL; } + buf = PyMem_MALLOC(MAXPATHLEN+1); + if (buf == NULL) { + return PyErr_NoMemory(); + } parent = get_parent(globals, buf, &buflen, level); if (parent == NULL) - return NULL; + goto error_exit; head = load_next(parent, level < 0 ? Py_None : parent, &name, buf, &buflen); if (head == NULL) - return NULL; + goto error_exit; tail = head; Py_INCREF(tail); @@ -2142,7 +2182,7 @@ import_module_level(char *name, PyObject *globals, PyObject *locals, Py_DECREF(tail); if (next == NULL) { Py_DECREF(head); - return NULL; + goto error_exit; } tail = next; } @@ -2154,7 +2194,7 @@ import_module_level(char *name, PyObject *globals, PyObject *locals, Py_DECREF(head); PyErr_SetString(PyExc_ValueError, "Empty module name"); - return NULL; + goto error_exit; } if (fromlist != NULL) { @@ -2164,16 +2204,22 @@ import_module_level(char *name, PyObject *globals, PyObject *locals, if (fromlist == NULL) { Py_DECREF(tail); + PyMem_FREE(buf); return head; } Py_DECREF(head); if (!ensure_fromlist(tail, fromlist, buf, buflen, 0)) { Py_DECREF(tail); - return NULL; + goto error_exit; } + PyMem_FREE(buf); return tail; + +error_exit: + PyMem_FREE(buf); + return NULL; } PyObject * @@ -2563,7 +2609,7 @@ import_submodule(PyObject *mod, char *subname, char *fullname) } else { PyObject *path, *loader = NULL; - char buf[MAXPATHLEN+1]; + char *buf; struct filedescr *fdp; FILE *fp = NULL; @@ -2578,11 +2624,16 @@ import_submodule(PyObject *mod, char *subname, char *fullname) } } + buf = PyMem_MALLOC(MAXPATHLEN+1); + if (buf == NULL) { + return PyErr_NoMemory(); + } buf[0] = '\0'; fdp = find_module(fullname, subname, path, buf, MAXPATHLEN+1, &fp, &loader); Py_XDECREF(path); if (fdp == NULL) { + PyMem_FREE(buf); if (!PyErr_ExceptionMatches(PyExc_ImportError)) return NULL; PyErr_Clear(); @@ -2597,6 +2648,7 @@ import_submodule(PyObject *mod, char *subname, char *fullname) Py_XDECREF(m); m = NULL; } + PyMem_FREE(buf); } return m; @@ -2614,7 +2666,7 @@ PyImport_ReloadModule(PyObject *m) PyObject *modules = PyImport_GetModuleDict(); PyObject *path = NULL, *loader = NULL, *existing_m = NULL; char *name, *subname; - char buf[MAXPATHLEN+1]; + char *buf; struct filedescr *fdp; FILE *fp = NULL; PyObject *newm; @@ -2674,6 +2726,11 @@ PyImport_ReloadModule(PyObject *m) if (path == NULL) PyErr_Clear(); } + buf = PyMem_MALLOC(MAXPATHLEN+1); + if (buf == NULL) { + Py_XDECREF(path); + return PyErr_NoMemory(); + } buf[0] = '\0'; fdp = find_module(name, subname, path, buf, MAXPATHLEN+1, &fp, &loader); Py_XDECREF(path); @@ -2681,6 +2738,7 @@ PyImport_ReloadModule(PyObject *m) if (fdp == NULL) { Py_XDECREF(loader); imp_modules_reloading_clear(); + PyMem_FREE(buf); return NULL; } @@ -2698,6 +2756,7 @@ PyImport_ReloadModule(PyObject *m) PyDict_SetItemString(modules, name, m); } imp_modules_reloading_clear(); + PyMem_FREE(buf); return newm; } @@ -2828,19 +2887,25 @@ call_find_module(char *name, PyObject *path) extern int fclose(FILE *); PyObject *fob, *ret; struct filedescr *fdp; - char pathname[MAXPATHLEN+1]; + char *pathname; FILE *fp = NULL; + pathname = PyMem_MALLOC(MAXPATHLEN+1); + if (pathname == NULL) { + return PyErr_NoMemory(); + } pathname[0] = '\0'; if (path == Py_None) path = NULL; fdp = find_module(NULL, name, path, pathname, MAXPATHLEN+1, &fp, NULL); - if (fdp == NULL) + if (fdp == NULL) { + PyMem_FREE(pathname); return NULL; + } if (fp != NULL) { fob = PyFile_FromFile(fp, pathname, fdp->mode, fclose); if (fob == NULL) { - fclose(fp); + PyMem_FREE(pathname); return NULL; } } @@ -2851,6 +2916,7 @@ call_find_module(char *name, PyObject *path) ret = Py_BuildValue("Os(ssi)", fob, pathname, fdp->suffix, fdp->mode, fdp->type); Py_DECREF(fob); + PyMem_FREE(pathname); return ret; } @@ -3198,49 +3264,11 @@ NullImporter_init(NullImporter *self, PyObject *args, PyObject *kwds) PyErr_SetString(PyExc_ImportError, "empty pathname"); return -1; } else { -#ifndef RISCOS -#ifndef MS_WINDOWS - struct stat statbuf; - int rv; - - rv = stat(path, &statbuf); - if (rv == 0) { - /* it exists */ - if (S_ISDIR(statbuf.st_mode)) { - /* it's a directory */ - PyErr_SetString(PyExc_ImportError, - "existing directory"); - return -1; - } - } -#else /* MS_WINDOWS */ - DWORD rv; - /* see issue1293 and issue3677: - * stat() on Windows doesn't recognise paths like - * "e:\\shared\\" and "\\\\whiterab-c2znlh\\shared" as dirs. - */ - rv = GetFileAttributesA(path); - if (rv != INVALID_FILE_ATTRIBUTES) { - /* it exists */ - if (rv & FILE_ATTRIBUTE_DIRECTORY) { - /* it's a directory */ - PyErr_SetString(PyExc_ImportError, - "existing directory"); - return -1; - } - } -#endif -#else /* RISCOS */ - if (object_exists(path)) { - /* it exists */ - if (isdir(path)) { - /* it's a directory */ - PyErr_SetString(PyExc_ImportError, - "existing directory"); - return -1; - } + if(isdir(path)) { + PyErr_SetString(PyExc_ImportError, + "existing directory"); + return -1; } -#endif } return 0; } @@ -3375,13 +3403,13 @@ PyImport_ExtendInittab(struct _inittab *newtab) /* Shorthand to add a single entry given a name and a function */ int -PyImport_AppendInittab(char *name, void (*initfunc)(void)) +PyImport_AppendInittab(const char *name, void (*initfunc)(void)) { struct _inittab newtab[2]; memset(newtab, '\0', sizeof newtab); - newtab[0].name = name; + newtab[0].name = (char *)name; newtab[0].initfunc = initfunc; return PyImport_ExtendInittab(newtab); |
