summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrett Cannon <brett@python.org>2012-04-15 21:56:09 (GMT)
committerBrett Cannon <brett@python.org>2012-04-15 21:56:09 (GMT)
commit8a1d04c64372d4706572671a21ff9d3e4a6374ca (patch)
treedb9e9c2ade3bdf16d917f61a76a2e27ee524af05
parent7ceedb8c1ec96f3aa1db9e7d2aed89c70481caad (diff)
downloadcpython-8a1d04c64372d4706572671a21ff9d3e4a6374ca.zip
cpython-8a1d04c64372d4706572671a21ff9d3e4a6374ca.tar.gz
cpython-8a1d04c64372d4706572671a21ff9d3e4a6374ca.tar.bz2
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.
-rw-r--r--Misc/NEWS3
-rw-r--r--Python/import.c44
2 files changed, 13 insertions, 34 deletions
diff --git a/Misc/NEWS b/Misc/NEWS
index 36b82d4..e2e14b7 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -32,6 +32,9 @@ Core and Builtins
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
re-implementing parts of the module in pure Python.
diff --git a/Python/import.c b/Python/import.c
index a930382..747b0dd 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -153,7 +153,6 @@ static const struct filedescr _PyImport_StandardFiletab[] = {
};
static PyObject *initstr = NULL;
-_Py_IDENTIFIER(__path__);
/* Initialize things */
@@ -3106,12 +3105,12 @@ PyImport_ReloadModule(PyObject *m)
PyInterpreterState *interp = PyThreadState_Get()->interp;
PyObject *modules_reloading = interp->modules_reloading;
PyObject *modules = PyImport_GetModuleDict();
- PyObject *path_list = NULL, *loader = NULL, *existing_m = NULL;
- PyObject *name, *bufobj, *subname;
+ PyObject *loader = NULL, *existing_m = NULL;
+ PyObject *name;
Py_ssize_t subname_start;
- struct filedescr *fdp;
- FILE *fp = NULL;
PyObject *newm = NULL;
+ _Py_IDENTIFIER(__loader__);
+ _Py_IDENTIFIER(load_module);
if (modules_reloading == NULL) {
Py_FatalError("PyImport_ReloadModule: "
@@ -3149,51 +3148,28 @@ PyImport_ReloadModule(PyObject *m)
subname_start = PyUnicode_FindChar(name, '.', 0,
PyUnicode_GET_LENGTH(name), -1);
- if (subname_start == -1) {
- Py_INCREF(name);
- subname = name;
- }
- else {
+ if (subname_start != -1) {
PyObject *parentname, *parent;
- Py_ssize_t len;
parentname = PyUnicode_Substring(name, 0, subname_start);
if (parentname == NULL) {
goto error;
}
parent = PyDict_GetItem(modules, parentname);
+ Py_XDECREF(parent);
if (parent == NULL) {
PyErr_Format(PyExc_ImportError,
"reload(): parent %R not in sys.modules",
parentname);
- Py_DECREF(parentname);
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);
+ loader = _PyObject_GetAttrId(m, &PyId___loader__);
+ if (loader == NULL) {
goto error;
}
-
- newm = load_module(name, fp, bufobj, fdp->type, loader);
- Py_XDECREF(bufobj);
- Py_XDECREF(loader);
-
- if (fp)
- fclose(fp);
+ newm = _PyObject_CallMethodId(loader, &PyId_load_module, "O", name);
+ Py_DECREF(loader);
if (newm == NULL) {
/* load_module probably removed name from modules because of
* the error. Put back the original module object. We're