Issue #3080: Create find_module_path() subfunction

This commit is contained in:
Victor Stinner 2011-03-12 16:02:28 -05:00
parent 3758028299
commit d68c2cf237

View file

@ -1598,57 +1598,53 @@ static int case_ok(char *, Py_ssize_t, Py_ssize_t, const char *);
static int find_init_module(char *); /* Forward */
static struct filedescr importhookdescr = {"", "", IMP_HOOK};
static struct filedescr*
find_module_path_list(char *fullname, const char *name,
PyObject *search_path_list, PyObject *path_hooks,
PyObject *path_importer_cache,
/* Get the path of a module: get its importer and call importer.find_module()
hook, or check if the module if a package (if path/__init__.py exists).
-1: error: a Python error occurred
0: ignore: an error occurred because of invalid data, but the error is not
important enough to be reported.
1: get path: module not found, but *buf contains its path
2: found: *p_fd is the file descriptor (IMP_HOOK or PKG_DIRECTORY)
and *buf is the path */
static int
find_module_path(char *fullname, const char *name, PyObject *path,
PyObject *path_hooks, PyObject *path_importer_cache,
char *buf, size_t buflen,
FILE **p_fp, PyObject **p_loader)
PyObject **p_loader, struct filedescr **p_fd)
{
Py_ssize_t i, npath;
size_t len, namelen;
struct filedescr *fdp = NULL;
char *filemode;
FILE *fp = NULL;
PyObject *path_bytes;
const char *base;
Py_ssize_t len;
size_t namelen;
struct stat statbuf;
static struct filedescr fd_package = {"", "", PKG_DIRECTORY};
#if defined(PYOS_OS2)
size_t saved_len;
size_t saved_namelen;
char *saved_buf = NULL;
#endif
npath = PyList_Size(search_path_list);
namelen = strlen(name);
for (i = 0; i < npath; i++) {
PyObject *v = PyList_GetItem(search_path_list, i);
PyObject *origv = v;
const char *base;
Py_ssize_t size;
if (!v)
return NULL;
if (PyUnicode_Check(v)) {
v = PyUnicode_EncodeFSDefault(v);
if (v == NULL)
return NULL;
if (PyUnicode_Check(path)) {
path_bytes = PyUnicode_EncodeFSDefault(path);
if (path_bytes == NULL)
return -1;
}
else if (PyBytes_Check(path)) {
Py_INCREF(path);
path_bytes = path;
}
else if (!PyBytes_Check(v))
continue;
else
Py_INCREF(v);
return 0;
base = PyBytes_AS_STRING(v);
size = PyBytes_GET_SIZE(v);
len = size;
namelen = strlen(name);
base = PyBytes_AS_STRING(path_bytes);
len = PyBytes_GET_SIZE(path_bytes);
if (len + 2 + namelen + MAXSUFFIXSIZE >= buflen) {
Py_DECREF(v);
continue; /* Too long */
Py_DECREF(path_bytes);
return 0; /* Too long */
}
strcpy(buf, base);
Py_DECREF(v);
Py_DECREF(path_bytes);
if (strlen(buf) != len) {
continue; /* v contains '\0' */
return 0; /* path_bytes contains '\0' */
}
/* sys.path_hooks import hook */
@ -1656,9 +1652,9 @@ find_module_path_list(char *fullname, const char *name,
PyObject *importer;
importer = get_path_importer(path_importer_cache,
path_hooks, origv);
path_hooks, path);
if (importer == NULL) {
return NULL;
return -1;
}
/* Note: importer is a borrowed reference */
if (importer != Py_None) {
@ -1667,14 +1663,15 @@ find_module_path_list(char *fullname, const char *name,
"find_module",
"s", fullname);
if (loader == NULL)
return NULL; /* error */
return -1; /* error */
if (loader != Py_None) {
/* a loader was found */
*p_loader = loader;
return &importhookdescr;
*p_fd = &importhookdescr;
return 2;
}
Py_DECREF(loader);
continue;
return 0;
}
}
/* no hook was found, use builtin import */
@ -1695,22 +1692,75 @@ find_module_path_list(char *fullname, const char *name,
S_ISDIR(statbuf.st_mode) && /* it's a directory */
case_ok(buf, len, namelen, name)) { /* case matches */
if (find_init_module(buf)) { /* and has __init__.py */
return &fd_package;
*p_fd = &fd_package;
return 2;
}
else {
int err;
PyObject *unicode = PyUnicode_DecodeFSDefault(buf);
if (unicode == NULL)
return NULL;
return -1;
err = PyErr_WarnFormat(PyExc_ImportWarning, 1,
"Not importing directory '%U': missing __init__.py",
unicode);
Py_DECREF(unicode);
if (err)
return NULL;
return -1;
}
}
#endif
return 1;
}
/* Find a module in search_path_list. For each path, try
find_module_filename() or try each _PyImport_Filetab suffix.
If the module is found, return a file descriptor, write the path in
*p_filename, write the pointer to the file object into *p_fp, and (if
p_loader is not NULL) the loader into *p_loader.
Otherwise, raise an exception and return NULL. */
static struct filedescr*
find_module_path_list(char *fullname, const char *name,
PyObject *search_path_list, PyObject *path_hooks,
PyObject *path_importer_cache,
char *buf, size_t buflen,
FILE **p_fp, PyObject **p_loader)
{
Py_ssize_t i, npath;
size_t len, namelen;
struct filedescr *fdp = NULL;
char *filemode;
FILE *fp = NULL;
#if defined(PYOS_OS2)
size_t saved_len;
size_t saved_namelen;
char *saved_buf = NULL;
#endif
npath = PyList_Size(search_path_list);
namelen = strlen(name);
for (i = 0; i < npath; i++) {
PyObject *path;
int ok;
path = PyList_GetItem(search_path_list, i);
if (path == NULL)
return NULL;
ok = find_module_path(fullname, name, path,
path_hooks, path_importer_cache,
buf, buflen,
p_loader, &fdp);
if (ok < 0)
return NULL;
if (ok == 0)
continue;
if (ok == 2)
return fdp;
len = strlen(buf);
#if defined(PYOS_OS2)
/* take a snapshot of the module spec for restoration
* after the 8 character DLL hackery