--- import.c.orig 2006-06-30 16:36:22.000000000 -0600 +++ import.c 2006-06-30 17:05:20.000000000 -0600 @@ -1086,6 +1086,7 @@ char *filemode; FILE *fp = NULL; PyObject *path_hooks, *path_importer_cache; + PyObject *warn_paths = NULL; #ifndef RISCOS struct stat statbuf; #endif @@ -1208,12 +1209,15 @@ for (i = 0; i < npath; i++) { PyObject *copy = NULL; PyObject *v = PyList_GetItem(path, i); + int is_a_dir; #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) + if (copy == NULL) { + Py_XDECREF(warn_paths); return NULL; + } v = copy; } else @@ -1237,8 +1241,11 @@ importer = get_path_importer(path_importer_cache, path_hooks, v); - if (importer == NULL) + if (importer == NULL) { + Py_XDECREF(warn_paths); + Py_XDECREF(copy); return NULL; + } /* Note: importer is a borrowed reference */ if (importer == Py_False) { /* Cached as not being a valid dir. */ @@ -1273,11 +1280,16 @@ loader = PyObject_CallMethod(importer, "find_module", "s", fullname); - if (loader == NULL) + if (loader == NULL) { + Py_XDECREF(warn_paths); + Py_XDECREF(copy); return NULL; /* error */ + } if (loader != Py_None) { /* a loader was found */ *p_loader = loader; + Py_XDECREF(warn_paths); + Py_XDECREF(copy); return &importhookdescr; } Py_DECREF(loader); @@ -1298,48 +1310,38 @@ /* Check for package import (buf holds a directory name, and there's an __init__ module in that directory */ +#if defined(HAVE_STAT) || defined(RISCOS) #ifdef HAVE_STAT - if (stat(buf, &statbuf) == 0 && /* it exists */ - S_ISDIR(statbuf.st_mode) && /* it's a directory */ + is_a_dir = stat(buf, &statbuf) == 0 && /* it exists */ + S_ISDIR(statbuf.st_mode); /* it's a directory */ +#else + is_a_dir = isdir(buf); +#endif + if (is_a_dir && case_ok(buf, len, namelen, name)) { /* case matches */ - if (find_init_module(buf)) { /* and has __init__.py */ + if (find_init_module(buf)) { /* has __init__.py */ + Py_XDECREF(warn_paths); 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; + PyObject *wp = PyString_FromString(buf); + if (wp) { + if (!warn_paths) + warn_paths = PyList_New(0); + if (warn_paths) + PyList_Append(warn_paths, wp); + Py_DECREF(wp); } - } - } -#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)) { + if (PyErr_Occurred()) { + Py_XDECREF(warn_paths); 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 @@ -1362,7 +1364,10 @@ scan = _PyImport_DynLoadFiletab; while (scan->suffix != NULL) { if (!strcmp(scan->suffix, fdp->suffix)) + { + Py_XDECREF(copy); break; + } else scan++; } @@ -1382,8 +1387,10 @@ filemode = "r" PY_STDIOTEXTMODE; fp = fopen(buf, filemode); if (fp != NULL) { - if (case_ok(buf, len, namelen, name)) + if (case_ok(buf, len, namelen, name)) { + Py_XDECREF(copy); break; + } else { /* continue search */ fclose(fp); fp = NULL; @@ -1409,10 +1416,26 @@ break; } if (fp == NULL) { + if (warn_paths) { + for (i = 0; i < PyList_Size(warn_paths); i++) { + char warnstr[MAXPATHLEN+80]; + char *wp = PyString_AS_STRING( + PyList_GET_ITEM(warn_paths, i)); + sprintf(warnstr, "Not importing directory " + "'%.*s': missing __init__.py", + MAXPATHLEN, wp); + if (PyErr_Warn(PyExc_ImportWarning, warnstr)) { + Py_DECREF(warn_paths); + return NULL; + } + } + Py_DECREF(warn_paths); + } PyErr_Format(PyExc_ImportError, "No module named %.200s", name); return NULL; } + Py_XDECREF(warn_paths); *p_fp = fp; return fdp; }