[Python-checkins] cpython: Issues #13959, 14647: Re-implement imp.reload() in Lib/imp.py.
brett.cannon
python-checkins at python.org
Sun Apr 29 20:40:50 CEST 2012
http://hg.python.org/cpython/rev/eb68502731dd
changeset: 76640:eb68502731dd
parent: 76637:1255cac63dfc
user: Brett Cannon <brett at python.org>
date: Sun Apr 29 14:38:11 2012 -0400
summary:
Issues #13959, 14647: Re-implement imp.reload() in Lib/imp.py.
Thanks to Eric Snow for the patch.
files:
Include/pystate.h | 1 -
Lib/imp.py | 33 ++++++++-
Objects/moduleobject.c | 2 +-
Python/import.c | 113 +++-------------------------
Python/pystate.c | 2 -
Python/pythonrun.c | 4 -
6 files changed, 47 insertions(+), 108 deletions(-)
diff --git a/Include/pystate.h b/Include/pystate.h
--- a/Include/pystate.h
+++ b/Include/pystate.h
@@ -26,7 +26,6 @@
PyObject *sysdict;
PyObject *builtins;
PyObject *importlib;
- PyObject *modules_reloading;
PyObject *codec_search_path;
PyObject *codec_search_cache;
diff --git a/Lib/imp.py b/Lib/imp.py
--- a/Lib/imp.py
+++ b/Lib/imp.py
@@ -6,7 +6,7 @@
"""
# (Probably) need to stay in _imp
-from _imp import (lock_held, acquire_lock, release_lock, reload,
+from _imp import (lock_held, acquire_lock, release_lock,
load_dynamic, get_frozen_object, is_frozen_package,
init_builtin, init_frozen, is_builtin, is_frozen,
_fix_co_filename)
@@ -207,3 +207,34 @@
encoding = tokenize.detect_encoding(file.readline)[0]
file = open(file_path, mode, encoding=encoding)
return file, file_path, (suffix, mode, type_)
+
+
+_RELOADING = {}
+
+def reload(module):
+ """Reload the module and return it.
+
+ The module must have been successfully imported before.
+
+ """
+ if not module or type(module) != type(sys):
+ raise TypeError("reload() argument must be module")
+ name = module.__name__
+ if name not in sys.modules:
+ msg = "module {} not in sys.modules"
+ raise ImportError(msg.format(name), name=name)
+ if name in _RELOADING:
+ return _RELOADING[name]
+ _RELOADING[name] = module
+ try:
+ parent_name = name.rpartition('.')[0]
+ if parent_name and parent_name not in sys.modules:
+ msg = "parent {!r} not in sys.modules"
+ raise ImportError(msg.format(parentname), name=parent_name)
+ return module.__loader__.load_module(name)
+ finally:
+ try:
+ del _RELOADING[name]
+ except KeyError:
+ pass
+
diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c
--- a/Objects/moduleobject.c
+++ b/Objects/moduleobject.c
@@ -285,7 +285,7 @@
pos = 0;
while (PyDict_Next(d, &pos, &key, &value)) {
if (value != Py_None && PyUnicode_Check(key)) {
- if (PyUnicode_READ_CHAR(key, 0) == '_' &&
+ if (PyUnicode_READ_CHAR(key, 0) == '_' &&
PyUnicode_READ_CHAR(key, 1) != '_') {
if (Py_VerboseFlag > 1) {
const char *s = _PyUnicode_AsString(key);
diff --git a/Python/import.c b/Python/import.c
--- a/Python/import.c
+++ b/Python/import.c
@@ -410,14 +410,6 @@
#endif
}
-static void
-imp_modules_reloading_clear(void)
-{
- PyInterpreterState *interp = PyThreadState_Get()->interp;
- if (interp->modules_reloading != NULL)
- PyDict_Clear(interp->modules_reloading);
-}
-
/* Helper for sys */
PyObject *
@@ -575,7 +567,6 @@
PyDict_Clear(modules);
interp->modules = NULL;
Py_DECREF(modules);
- Py_CLEAR(interp->modules_reloading);
}
@@ -1783,87 +1774,23 @@
PyObject *
PyImport_ReloadModule(PyObject *m)
{
- PyInterpreterState *interp = PyThreadState_Get()->interp;
- PyObject *modules_reloading = interp->modules_reloading;
+ _Py_IDENTIFIER(reload);
+ PyObject *reloaded_module = NULL;
PyObject *modules = PyImport_GetModuleDict();
- PyObject *loader = NULL, *existing_m = NULL;
- PyObject *name;
- Py_ssize_t subname_start;
- PyObject *newm = NULL;
- _Py_IDENTIFIER(__loader__);
- _Py_IDENTIFIER(load_module);
-
- if (modules_reloading == NULL) {
- Py_FatalError("PyImport_ReloadModule: "
- "no modules_reloading dictionary!");
- return NULL;
+ PyObject *imp = PyDict_GetItemString(modules, "imp");
+ if (imp == NULL) {
+ imp = PyImport_ImportModule("imp");
+ if (imp == NULL) {
+ return NULL;
+ }
+ }
+ else {
+ Py_INCREF(imp);
}
- if (m == NULL || !PyModule_Check(m)) {
- PyErr_SetString(PyExc_TypeError,
- "reload() argument must be module");
- return NULL;
- }
- name = PyModule_GetNameObject(m);
- if (name == NULL || PyUnicode_READY(name) == -1)
- return NULL;
- if (m != PyDict_GetItem(modules, name)) {
- PyErr_Format(PyExc_ImportError,
- "reload(): module %R not in sys.modules",
- name);
- Py_DECREF(name);
- return NULL;
- }
- existing_m = PyDict_GetItem(modules_reloading, name);
- if (existing_m != NULL) {
- /* Due to a recursive reload, this module is already
- being reloaded. */
- Py_DECREF(name);
- Py_INCREF(existing_m);
- return existing_m;
- }
- if (PyDict_SetItem(modules_reloading, name, m) < 0) {
- Py_DECREF(name);
- return NULL;
- }
-
- subname_start = PyUnicode_FindChar(name, '.', 0,
- PyUnicode_GET_LENGTH(name), -1);
- if (subname_start != -1) {
- PyObject *parentname, *parent;
- 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);
- goto error;
- }
- }
-
- loader = _PyObject_GetAttrId(m, &PyId___loader__);
- if (loader == NULL) {
- goto error;
- }
- 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
- * going to return NULL in this case regardless of whether
- * replacing name succeeds, so the return value is ignored.
- */
- PyDict_SetItem(modules, name, m);
- }
-
-error:
- imp_modules_reloading_clear();
- Py_DECREF(name);
- return newm;
+ reloaded_module = _PyObject_CallMethodId(imp, &PyId_reload, "O", m);
+ Py_DECREF(imp);
+ return reloaded_module;
}
@@ -2160,17 +2087,6 @@
#endif /* HAVE_DYNAMIC_LOADING */
-static PyObject *
-imp_reload(PyObject *self, PyObject *v)
-{
- return PyImport_ReloadModule(v);
-}
-
-PyDoc_STRVAR(doc_reload,
-"reload(module) -> module\n\
-\n\
-Reload the module. The module must have been successfully imported before.");
-
/* Doc strings */
@@ -2214,7 +2130,6 @@
{"lock_held", imp_lock_held, METH_NOARGS, doc_lock_held},
{"acquire_lock", imp_acquire_lock, METH_NOARGS, doc_acquire_lock},
{"release_lock", imp_release_lock, METH_NOARGS, doc_release_lock},
- {"reload", imp_reload, METH_O, doc_reload},
{"get_frozen_object", imp_get_frozen_object, METH_VARARGS},
{"is_frozen_package", imp_is_frozen_package, METH_VARARGS},
{"init_builtin", imp_init_builtin, METH_VARARGS},
diff --git a/Python/pystate.c b/Python/pystate.c
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -69,7 +69,6 @@
Py_FatalError("Can't initialize threads for interpreter");
#endif
interp->modules = NULL;
- interp->modules_reloading = NULL;
interp->modules_by_index = NULL;
interp->sysdict = NULL;
interp->builtins = NULL;
@@ -114,7 +113,6 @@
Py_CLEAR(interp->codec_error_registry);
Py_CLEAR(interp->modules);
Py_CLEAR(interp->modules_by_index);
- Py_CLEAR(interp->modules_reloading);
Py_CLEAR(interp->sysdict);
Py_CLEAR(interp->builtins);
Py_CLEAR(interp->importlib);
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -314,9 +314,6 @@
interp->modules = PyDict_New();
if (interp->modules == NULL)
Py_FatalError("Py_Initialize: can't make modules dictionary");
- interp->modules_reloading = PyDict_New();
- if (interp->modules_reloading == NULL)
- Py_FatalError("Py_Initialize: can't make modules_reloading dictionary");
/* Init Unicode implementation; relies on the codec registry */
if (_PyUnicode_Init() < 0)
@@ -680,7 +677,6 @@
/* XXX The following is lax in error checking */
interp->modules = PyDict_New();
- interp->modules_reloading = PyDict_New();
bimod = _PyImport_FindBuiltin("builtins");
if (bimod != NULL) {
--
Repository URL: http://hg.python.org/cpython
More information about the Python-checkins
mailing list