Issue #13959: Simplify imp.reload() by relying on a module's

__loader__.

Since import now sets __loader__ on all modules it creates and
imp.reload() already relied on the attribute for modules that import
didn't create, the only potential compatibility issue is if people
were deleting the attribute on modules and expecting imp.reload() to
continue to work.
This commit is contained in:
Brett Cannon 2012-04-15 17:56:09 -04:00
parent 7ceedb8c1e
commit 8a1d04c643
2 changed files with 15 additions and 36 deletions

View file

@ -32,6 +32,9 @@ Core and Builtins
Library Library
------- -------
- Issue #13959: Make imp.reload() always use a module's __loader__ to perform
the reload.
- Issue #13959: Add imp.py and rename the built-in module to _imp, allowing for - Issue #13959: Add imp.py and rename the built-in module to _imp, allowing for
re-implementing parts of the module in pure Python. re-implementing parts of the module in pure Python.

View file

@ -153,7 +153,6 @@ static const struct filedescr _PyImport_StandardFiletab[] = {
}; };
static PyObject *initstr = NULL; static PyObject *initstr = NULL;
_Py_IDENTIFIER(__path__);
/* Initialize things */ /* Initialize things */
@ -3106,12 +3105,12 @@ PyImport_ReloadModule(PyObject *m)
PyInterpreterState *interp = PyThreadState_Get()->interp; PyInterpreterState *interp = PyThreadState_Get()->interp;
PyObject *modules_reloading = interp->modules_reloading; PyObject *modules_reloading = interp->modules_reloading;
PyObject *modules = PyImport_GetModuleDict(); PyObject *modules = PyImport_GetModuleDict();
PyObject *path_list = NULL, *loader = NULL, *existing_m = NULL; PyObject *loader = NULL, *existing_m = NULL;
PyObject *name, *bufobj, *subname; PyObject *name;
Py_ssize_t subname_start; Py_ssize_t subname_start;
struct filedescr *fdp;
FILE *fp = NULL;
PyObject *newm = NULL; PyObject *newm = NULL;
_Py_IDENTIFIER(__loader__);
_Py_IDENTIFIER(load_module);
if (modules_reloading == NULL) { if (modules_reloading == NULL) {
Py_FatalError("PyImport_ReloadModule: " Py_FatalError("PyImport_ReloadModule: "
@ -3149,51 +3148,28 @@ PyImport_ReloadModule(PyObject *m)
subname_start = PyUnicode_FindChar(name, '.', 0, subname_start = PyUnicode_FindChar(name, '.', 0,
PyUnicode_GET_LENGTH(name), -1); PyUnicode_GET_LENGTH(name), -1);
if (subname_start == -1) { if (subname_start != -1) {
Py_INCREF(name);
subname = name;
}
else {
PyObject *parentname, *parent; PyObject *parentname, *parent;
Py_ssize_t len;
parentname = PyUnicode_Substring(name, 0, subname_start); parentname = PyUnicode_Substring(name, 0, subname_start);
if (parentname == NULL) { if (parentname == NULL) {
goto error; goto error;
} }
parent = PyDict_GetItem(modules, parentname); parent = PyDict_GetItem(modules, parentname);
Py_XDECREF(parent);
if (parent == NULL) { if (parent == NULL) {
PyErr_Format(PyExc_ImportError, PyErr_Format(PyExc_ImportError,
"reload(): parent %R not in sys.modules", "reload(): parent %R not in sys.modules",
parentname); parentname);
Py_DECREF(parentname);
goto error; goto error;
} }
Py_DECREF(parentname);
path_list = _PyObject_GetAttrId(parent, &PyId___path__);
if (path_list == NULL)
PyErr_Clear();
subname_start++;
len = PyUnicode_GET_LENGTH(name) - (subname_start + 1);
subname = PyUnicode_Substring(name, subname_start, len);
}
if (subname == NULL)
goto error;
fdp = find_module(name, subname, path_list,
&bufobj, &fp, &loader);
Py_DECREF(subname);
Py_XDECREF(path_list);
if (fdp == NULL) {
Py_XDECREF(loader);
goto error;
} }
newm = load_module(name, fp, bufobj, fdp->type, loader); loader = _PyObject_GetAttrId(m, &PyId___loader__);
Py_XDECREF(bufobj); if (loader == NULL) {
Py_XDECREF(loader); goto error;
}
if (fp) newm = _PyObject_CallMethodId(loader, &PyId_load_module, "O", name);
fclose(fp); Py_DECREF(loader);
if (newm == NULL) { if (newm == NULL) {
/* load_module probably removed name from modules because of /* load_module probably removed name from modules because of
* the error. Put back the original module object. We're * the error. Put back the original module object. We're