summaryrefslogtreecommitdiff
path: root/Python/import.c
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@haypocalc.com>2011-03-20 01:34:43 +0100
committerVictor Stinner <victor.stinner@haypocalc.com>2011-03-20 01:34:43 +0100
commit375802829991b577c03b9a563469820097aff255 (patch)
treedff4fe87c56a08f7e2541ea40c967c7667983035 /Python/import.c
parentc6963164663ef99eebe8b827d9043bbba0cc0b11 (diff)
downloadcpython-git-375802829991b577c03b9a563469820097aff255.tar.gz
Issue #3080: Create find_module_path_list() subfunction
Diffstat (limited to 'Python/import.c')
-rw-r--r--Python/import.c310
1 files changed, 164 insertions, 146 deletions
diff --git a/Python/import.c b/Python/import.c
index 37cd4b81f2..565f1336cb 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -1598,168 +1598,30 @@ 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};
-/* Find a module:
-
- - try find_module() of each sys.meta_path hook
- - try find_frozen()
- - try is_builtin()
- - try _PyWin_FindRegisteredModule() (Windows only)
- - otherwise, call find_module_path_list() with search_path_list (if not
- NULL) or sys.path
-
- Return:
-
- - &fd_builtin (C_BUILTIN) if it is a builtin
- - &fd_frozen (PY_FROZEN) if it is frozen
- - &fd_package (PKG_DIRECTORY) and write the filename into *buf
- if it is a package
- - &importhookdescr (IMP_HOOK) and write the loader into *p_loader if a
- importer loader was found
- - a file descriptor (PY_SOURCE, PY_COMPILED, C_EXTENSION, PY_RESOURCE or
- PY_CODERESOURCE: see _PyImport_Filetab), write the filename into
- *buf and the pointer to the open file into *p_fp
- - NULL on error
-
- By default, write an empty string into *buf, and *p_fp and *p_loader (if
- set) are set to NULL. Eg. *buf is an empty string for a builtin package. */
-
-static struct filedescr *
-find_module(char *fullname, const char *name, PyObject *path, char *buf,
- size_t buflen, FILE **p_fp, PyObject **p_loader)
+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;
- PyObject *path_hooks, *path_importer_cache;
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 defined(PYOS_OS2)
size_t saved_len;
size_t saved_namelen;
char *saved_buf = NULL;
#endif
- PyObject *fullname_obj, *nameobj;
- *buf = '\0';
- *p_fp = NULL;
- if (p_loader != NULL)
- *p_loader = NULL;
-
- if (strlen(name) > MAXPATHLEN) {
- PyErr_SetString(PyExc_OverflowError,
- "module name is too long");
- return NULL;
- }
-
- /* sys.meta_path import hook */
- if (p_loader != NULL) {
- PyObject *meta_path;
-
- meta_path = PySys_GetObject("meta_path");
- if (meta_path == NULL || !PyList_Check(meta_path)) {
- PyErr_SetString(PyExc_ImportError,
- "sys.meta_path must be a list of "
- "import hooks");
- return NULL;
- }
- Py_INCREF(meta_path); /* zap guard */
- npath = PyList_Size(meta_path);
- for (i = 0; i < npath; i++) {
- PyObject *loader;
- PyObject *hook = PyList_GetItem(meta_path, i);
- loader = PyObject_CallMethod(hook, "find_module",
- "sO", fullname,
- path != NULL ?
- path : Py_None);
- if (loader == NULL) {
- Py_DECREF(meta_path);
- return NULL; /* true error */
- }
- if (loader != Py_None) {
- /* a loader was found */
- *p_loader = loader;
- Py_DECREF(meta_path);
- return &importhookdescr;
- }
- Py_DECREF(loader);
- }
- Py_DECREF(meta_path);
- }
-
- if (fullname != NULL) {
- fullname_obj = PyUnicode_FromString(fullname);
- if (fullname == NULL)
- return NULL;
- if (find_frozen(fullname_obj) != NULL) {
- Py_DECREF(fullname_obj);
- strcpy(buf, fullname);
- return &fd_frozen;
- }
- Py_DECREF(fullname_obj);
- }
-
- if (path == NULL) {
-#ifdef MS_COREDLL
- PyObject *filename, *filename_bytes;
-#endif
- nameobj = PyUnicode_FromString(name);
- if (nameobj == NULL)
- return NULL;
- if (is_builtin(nameobj)) {
- Py_DECREF(nameobj);
- strcpy(buf, name);
- return &fd_builtin;
- }
-#ifdef MS_COREDLL
- fp = _PyWin_FindRegisteredModule(nameobj, &fdp, &filename);
- if (fp != NULL) {
- Py_DECREF(nameobj);
- filename_bytes = PyUnicode_EncodeFSDefault(filename);
- Py_DECREF(filename);
- if (filename_bytes == NULL)
- return NULL;
- strncpy(buf, PyBytes_AS_STRING(filename_bytes), buflen);
- buf[buflen-1] = '\0';
- Py_DECREF(filename_bytes);
- *p_fp = fp;
- return fdp;
- }
- else if (PyErr_Occurred())
- return NULL;
-#endif
- Py_DECREF(nameobj);
- path = PySys_GetObject("path");
- }
-
- if (path == NULL || !PyList_Check(path)) {
- PyErr_SetString(PyExc_ImportError,
- "sys.path must be a list of directory names");
- return NULL;
- }
-
- path_hooks = PySys_GetObject("path_hooks");
- if (path_hooks == NULL || !PyList_Check(path_hooks)) {
- PyErr_SetString(PyExc_ImportError,
- "sys.path_hooks must be a list of "
- "import hooks");
- return NULL;
- }
- path_importer_cache = PySys_GetObject("path_importer_cache");
- if (path_importer_cache == NULL ||
- !PyDict_Check(path_importer_cache)) {
- PyErr_SetString(PyExc_ImportError,
- "sys.path_importer_cache must be a dict");
- return NULL;
- }
-
- npath = PyList_Size(path);
+ npath = PyList_Size(search_path_list);
namelen = strlen(name);
for (i = 0; i < npath; i++) {
- PyObject *v = PyList_GetItem(path, i);
+ PyObject *v = PyList_GetItem(search_path_list, i);
PyObject *origv = v;
const char *base;
Py_ssize_t size;
@@ -1925,6 +1787,162 @@ find_module(char *fullname, const char *name, PyObject *path, char *buf,
return fdp;
}
+/* Find a module:
+
+ - try find_module() of each sys.meta_path hook
+ - try find_frozen()
+ - try is_builtin()
+ - try _PyWin_FindRegisteredModule() (Windows only)
+ - otherwise, call find_module_path_list() with search_path_list (if not
+ NULL) or sys.path
+
+ Return:
+
+ - &fd_builtin (C_BUILTIN) if it is a builtin
+ - &fd_frozen (PY_FROZEN) if it is frozen
+ - &fd_package (PKG_DIRECTORY) and write the filename into *buf
+ if it is a package
+ - &importhookdescr (IMP_HOOK) and write the loader into *p_loader if a
+ importer loader was found
+ - a file descriptor (PY_SOURCE, PY_COMPILED, C_EXTENSION, PY_RESOURCE or
+ PY_CODERESOURCE: see _PyImport_Filetab), write the filename into
+ *buf and the pointer to the open file into *p_fp
+ - NULL on error
+
+ By default, write an empty string into *buf, and *p_fp and *p_loader (if
+ set) are set to NULL. Eg. *buf is an empty string for a builtin package. */
+
+static struct filedescr *
+find_module(char *fullname, const char *name, PyObject *search_path_list,
+ char *buf, size_t buflen, FILE **p_fp, PyObject **p_loader)
+{
+ Py_ssize_t i, npath;
+ static struct filedescr fd_frozen = {"", "", PY_FROZEN};
+ static struct filedescr fd_builtin = {"", "", C_BUILTIN};
+ PyObject *path_hooks, *path_importer_cache;
+ PyObject *fullname_obj, *nameobj;
+
+ *buf = '\0';
+ *p_fp = NULL;
+ if (p_loader != NULL)
+ *p_loader = NULL;
+
+ if (strlen(name) > MAXPATHLEN) {
+ PyErr_SetString(PyExc_OverflowError,
+ "module name is too long");
+ return NULL;
+ }
+
+ /* sys.meta_path import hook */
+ if (p_loader != NULL) {
+ PyObject *meta_path;
+
+ meta_path = PySys_GetObject("meta_path");
+ if (meta_path == NULL || !PyList_Check(meta_path)) {
+ PyErr_SetString(PyExc_ImportError,
+ "sys.meta_path must be a list of "
+ "import hooks");
+ return NULL;
+ }
+ Py_INCREF(meta_path); /* zap guard */
+ npath = PyList_Size(meta_path);
+ for (i = 0; i < npath; i++) {
+ PyObject *loader;
+ PyObject *hook = PyList_GetItem(meta_path, i);
+ loader = PyObject_CallMethod(hook, "find_module",
+ "sO", fullname,
+ search_path_list != NULL ?
+ search_path_list : Py_None);
+ if (loader == NULL) {
+ Py_DECREF(meta_path);
+ return NULL; /* true error */
+ }
+ if (loader != Py_None) {
+ /* a loader was found */
+ *p_loader = loader;
+ Py_DECREF(meta_path);
+ return &importhookdescr;
+ }
+ Py_DECREF(loader);
+ }
+ Py_DECREF(meta_path);
+ }
+
+ if (fullname != NULL) {
+ fullname_obj = PyUnicode_FromString(fullname);
+ if (fullname == NULL)
+ return NULL;
+ if (find_frozen(fullname_obj) != NULL) {
+ Py_DECREF(fullname_obj);
+ strcpy(buf, fullname);
+ return &fd_frozen;
+ }
+ Py_DECREF(fullname_obj);
+ }
+
+ if (search_path_list == NULL) {
+#ifdef MS_COREDLL
+ FILE *fp;
+ struct filedescr *fdp;
+ PyObject *filename, *filename_bytes;
+#endif
+ nameobj = PyUnicode_FromString(name);
+ if (nameobj == NULL)
+ return NULL;
+ if (is_builtin(nameobj)) {
+ Py_DECREF(nameobj);
+ strcpy(buf, name);
+ return &fd_builtin;
+ }
+#ifdef MS_COREDLL
+ fp = _PyWin_FindRegisteredModule(nameobj, &fdp, &filename);
+ if (fp != NULL) {
+ Py_DECREF(nameobj);
+ filename_bytes = PyUnicode_EncodeFSDefault(filename);
+ Py_DECREF(filename);
+ if (filename_bytes == NULL)
+ return NULL;
+ strncpy(buf, PyBytes_AS_STRING(filename_bytes), buflen);
+ buf[buflen-1] = '\0';
+ Py_DECREF(filename_bytes);
+ *p_fp = fp;
+ return fdp;
+ }
+ else if (PyErr_Occurred())
+ return NULL;
+#endif
+ Py_DECREF(nameobj);
+ search_path_list = PySys_GetObject("path");
+ }
+
+ if (search_path_list == NULL || !PyList_Check(search_path_list)) {
+ PyErr_SetString(PyExc_ImportError,
+ "sys.path must be a list of directory names");
+ return NULL;
+ }
+
+ path_hooks = PySys_GetObject("path_hooks");
+ if (path_hooks == NULL || !PyList_Check(path_hooks)) {
+ PyErr_SetString(PyExc_ImportError,
+ "sys.path_hooks must be a list of "
+ "import hooks");
+ return NULL;
+ }
+ path_importer_cache = PySys_GetObject("path_importer_cache");
+ if (path_importer_cache == NULL ||
+ !PyDict_Check(path_importer_cache)) {
+ PyErr_SetString(PyExc_ImportError,
+ "sys.path_importer_cache must be a dict");
+ return NULL;
+ }
+
+ return find_module_path_list(fullname, name,
+ search_path_list, path_hooks,
+ path_importer_cache,
+ buf, buflen,
+ p_fp, p_loader);
+}
+
/* case_ok(char* buf, Py_ssize_t len, Py_ssize_t namelen, char* name)
* The arguments here are tricky, best shown by example:
* /a/b/c/d/e/f/g/h/i/j/k/some_long_module_name.py\0