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.
This commit is contained in:
Brett Cannon 2012-04-15 22:28:28 -04:00
parent 01a76171a0
commit 2ee61422ed
2 changed files with 17 additions and 173 deletions

View File

@ -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, from _imp import (get_magic, get_tag, get_suffixes, cache_from_source,
source_from_cache) source_from_cache)
# Should be re-implemented here (and mostly deprecated) # Should be re-implemented here (and mostly deprecated)
from _imp import (find_module, load_compiled, from _imp import (find_module, load_compiled, load_source, NullImporter,
load_package, load_source, NullImporter,
SEARCH_ERROR, PY_SOURCE, PY_COMPILED, C_EXTENSION, SEARCH_ERROR, PY_SOURCE, PY_COMPILED, C_EXTENSION,
PY_RESOURCE, PKG_DIRECTORY, C_BUILTIN, PY_FROZEN, PY_RESOURCE, PKG_DIRECTORY, C_BUILTIN, PY_FROZEN,
PY_CODERESOURCE, IMP_HOOK) PY_CODERESOURCE, IMP_HOOK)
from importlib._bootstrap import _new_module as new_module 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): def load_module(name, file, filename, details):
"""Load a module, given information returned by find_module(). """Load a module, given information returned by find_module().

View File

@ -1602,65 +1602,10 @@ unchanged:
} }
/* Forward */ /* Forward */
static PyObject *load_module(PyObject *, FILE *, PyObject *, int, PyObject *);
static struct filedescr *find_module(PyObject *, PyObject *, PyObject *, static struct filedescr *find_module(PyObject *, PyObject *, PyObject *,
PyObject **, FILE **, PyObject **); PyObject **, FILE **, PyObject **);
static struct _frozen * find_frozen(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 */ /* Helper to test for built-in module */
@ -2434,108 +2379,6 @@ find_init_module(PyObject *directory)
static int init_builtin(PyObject *); /* Forward */ 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. /* Initialize a built-in module.
Return 1 for success, 0 if the module is not found, and -1 with Return 1 for success, 0 if the module is not found, and -1 with
an exception set if the initialization failed. */ an exception set if the initialization failed. */
@ -3600,19 +3443,6 @@ imp_load_source(PyObject *self, PyObject *args)
return m; 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 * static PyObject *
imp_reload(PyObject *self, PyObject *v) imp_reload(PyObject *self, PyObject *v)
{ {
@ -3764,7 +3594,6 @@ static PyMethodDef imp_methods[] = {
#ifdef HAVE_DYNAMIC_LOADING #ifdef HAVE_DYNAMIC_LOADING
{"load_dynamic", imp_load_dynamic, METH_VARARGS}, {"load_dynamic", imp_load_dynamic, METH_VARARGS},
#endif #endif
{"load_package", imp_load_package, METH_VARARGS},
{"load_source", imp_load_source, METH_VARARGS}, {"load_source", imp_load_source, METH_VARARGS},
{"_fix_co_filename", imp_fix_co_filename, METH_VARARGS}, {"_fix_co_filename", imp_fix_co_filename, METH_VARARGS},
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */