From 2ee61422ed2d9069e11ce685823bd247b5a2e4e6 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Sun, 15 Apr 2012 22:28:28 -0400 Subject: [PATCH] Issue #13959: Re-implement imp.load_package() in imp.py. Thanks to Eric Snow for helping with imp.load_module() (previous commit) which led to the removal of a bunch of C code. --- Lib/imp.py | 19 +++++- Python/import.c | 171 ------------------------------------------------ 2 files changed, 17 insertions(+), 173 deletions(-) diff --git a/Lib/imp.py b/Lib/imp.py index 1d7742ded43..62623b63001 100644 --- a/Lib/imp.py +++ b/Lib/imp.py @@ -14,14 +14,29 @@ from _imp import (lock_held, acquire_lock, release_lock, reload, from _imp import (get_magic, get_tag, get_suffixes, cache_from_source, source_from_cache) # Should be re-implemented here (and mostly deprecated) -from _imp import (find_module, load_compiled, - load_package, load_source, NullImporter, +from _imp import (find_module, load_compiled, load_source, NullImporter, SEARCH_ERROR, PY_SOURCE, PY_COMPILED, C_EXTENSION, PY_RESOURCE, PKG_DIRECTORY, C_BUILTIN, PY_FROZEN, PY_CODERESOURCE, IMP_HOOK) from importlib._bootstrap import _new_module as new_module +from importlib import _bootstrap +import os + + +def load_package(name, path): + if os.path.isdir(path): + extensions = _bootstrap._suffix_list(PY_SOURCE) + extensions += _bootstrap._suffix_list(PY_COMPILED) + for extension in extensions: + path = os.path.join(path, '__init__'+extension) + if os.path.exists(path): + break + else: + raise ValueError('{!r} is not a package'.format(path)) + return _bootstrap._SourceFileLoader(name, path).load_module(name) + def load_module(name, file, filename, details): """Load a module, given information returned by find_module(). diff --git a/Python/import.c b/Python/import.c index 06830fe2cb6..1b93b7c096b 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1602,65 +1602,10 @@ unchanged: } /* Forward */ -static PyObject *load_module(PyObject *, FILE *, PyObject *, int, PyObject *); static struct filedescr *find_module(PyObject *, PyObject *, PyObject *, PyObject **, FILE **, PyObject **); static struct _frozen * find_frozen(PyObject *); -/* Load a package and return its module object WITH INCREMENTED - REFERENCE COUNT */ - -static PyObject * -load_package(PyObject *name, PyObject *pathname) -{ - PyObject *m, *d, *bufobj; - PyObject *file = NULL, *path_list = NULL; - int err; - FILE *fp = NULL; - struct filedescr *fdp; - - m = PyImport_AddModuleObject(name); - if (m == NULL) - return NULL; - if (Py_VerboseFlag) - PySys_FormatStderr("import %U # directory %R\n", - name, pathname); - file = get_sourcefile(pathname); - if (file == NULL) - return NULL; - path_list = Py_BuildValue("[O]", file); - if (path_list == NULL) { - Py_DECREF(file); - return NULL; - } - d = PyModule_GetDict(m); - err = PyDict_SetItemString(d, "__file__", file); - Py_DECREF(file); - if (err == 0) - err = PyDict_SetItemString(d, "__path__", path_list); - if (err != 0) { - Py_DECREF(path_list); - return NULL; - } - fdp = find_module(name, initstr, path_list, - &bufobj, &fp, NULL); - Py_DECREF(path_list); - if (fdp == NULL) { - if (PyErr_ExceptionMatches(PyExc_ImportError)) { - PyErr_Clear(); - Py_INCREF(m); - return m; - } - else - return NULL; - } - m = load_module(name, fp, bufobj, fdp->type, NULL); - Py_XDECREF(bufobj); - if (fp != NULL) - fclose(fp); - return m; -} - /* Helper to test for built-in module */ @@ -2434,108 +2379,6 @@ find_init_module(PyObject *directory) static int init_builtin(PyObject *); /* Forward */ -static PyObject* -load_builtin(PyObject *name, int type) -{ - PyObject *m, *modules; - int err; - - if (type == C_BUILTIN) - err = init_builtin(name); - else - err = PyImport_ImportFrozenModuleObject(name); - if (err < 0) - return NULL; - if (err == 0) { - PyErr_Format(PyExc_ImportError, - "Purported %s module %R not found", - type == C_BUILTIN ? "builtin" : "frozen", - name); - return NULL; - } - - modules = PyImport_GetModuleDict(); - m = PyDict_GetItem(modules, name); - if (m == NULL) { - PyErr_Format( - PyExc_ImportError, - "%s module %R not properly initialized", - type == C_BUILTIN ? "builtin" : "frozen", - name); - return NULL; - } - Py_INCREF(m); - return m; -} - -/* Load an external module using the default search path and return - its module object WITH INCREMENTED REFERENCE COUNT */ - -static PyObject * -load_module(PyObject *name, FILE *fp, PyObject *pathname, int type, PyObject *loader) -{ - PyObject *m; - - /* First check that there's an open file (if we need one) */ - switch (type) { - case PY_SOURCE: - case PY_COMPILED: - if (fp == NULL) { - PyErr_Format(PyExc_ValueError, - "file object required for import (type code %d)", - type); - return NULL; - } - } - - switch (type) { - - case PY_SOURCE: - m = load_source_module(name, pathname, fp); - break; - - case PY_COMPILED: - m = load_compiled_module(name, pathname, fp); - break; - -#ifdef HAVE_DYNAMIC_LOADING - case C_EXTENSION: - m = _PyImport_LoadDynamicModule(name, pathname, fp); - break; -#endif - - case PKG_DIRECTORY: - m = load_package(name, pathname); - break; - - case C_BUILTIN: - case PY_FROZEN: - m = load_builtin(name, type); - break; - - case IMP_HOOK: { - _Py_IDENTIFIER(load_module); - if (loader == NULL) { - PyErr_SetString(PyExc_ImportError, - "import hook without loader"); - return NULL; - } - m = _PyObject_CallMethodId(loader, &PyId_load_module, "O", name); - break; - } - - default: - PyErr_Format(PyExc_ImportError, - "Don't know how to import %R (type code %d)", - name, type); - m = NULL; - - } - - return m; -} - - /* Initialize a built-in module. Return 1 for success, 0 if the module is not found, and -1 with an exception set if the initialization failed. */ @@ -3600,19 +3443,6 @@ imp_load_source(PyObject *self, PyObject *args) return m; } -static PyObject * -imp_load_package(PyObject *self, PyObject *args) -{ - PyObject *name, *pathname; - PyObject * ret; - if (!PyArg_ParseTuple(args, "UO&:load_package", - &name, PyUnicode_FSDecoder, &pathname)) - return NULL; - ret = load_package(name, pathname); - Py_DECREF(pathname); - return ret; -} - static PyObject * imp_reload(PyObject *self, PyObject *v) { @@ -3764,7 +3594,6 @@ static PyMethodDef imp_methods[] = { #ifdef HAVE_DYNAMIC_LOADING {"load_dynamic", imp_load_dynamic, METH_VARARGS}, #endif - {"load_package", imp_load_package, METH_VARARGS}, {"load_source", imp_load_source, METH_VARARGS}, {"_fix_co_filename", imp_fix_co_filename, METH_VARARGS}, {NULL, NULL} /* sentinel */