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:
parent
01a76171a0
commit
2ee61422ed
19
Lib/imp.py
19
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().
|
||||
|
|
171
Python/import.c
171
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 */
|
||||
|
|
Loading…
Reference in New Issue