comparing with /home/esnow/projects/.external/.cpython searching for changes changeset: 76466:6b1232a2cc30 tag: issue13959_reload.diff tag: qbase tag: qtip tag: tip user: Eric Snow date: Sun Apr 22 07:05:06 2012 +0000 summary: [issue 13959] port _imp.reload to imp.py 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) @@ -194,3 +194,35 @@ encoding = tokenize.detect_encoding(file.readline)[0] file = open(file_path, mode, encoding=encoding) return file, file_path, (suffix, mode, type_) + + +# an alternate, more strict implementation (a la import.c) +def _reload(module, *, _reloading={}): + """Reload the module and return it. + + The module must have been successfully imported before. + + """ + if not module or type(module) != type(_imp): + raise TypeError("reload() argument must be module") + name = module.__name__ + if name not in sys.modules: + msg = "reload(): module {} not in sys.modules" + raise ImportError(msg.format(name)) + if fullname in _reloading: + return _reloading[fullname] + _reloading[fullname] = module + parentname = name.rpartition('.')[0] + if parentname is not None and parentname not in sys.modules: + msg = "reload(): parent %R not in sys.modules" + raise ImportError(msg.format(parentname)) + return module.__loader__.load_module(name) + + +def reload(module): + """Reload the module and return it. + + The module must have been successfully imported before. + + """ + return module.__loader__.load_module(module.__name__) diff --git a/Python/import.c b/Python/import.c --- a/Python/import.c +++ b/Python/import.c @@ -414,14 +414,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 * @@ -579,7 +571,6 @@ PyDict_Clear(modules); interp->modules = NULL; Py_DECREF(modules); - Py_CLEAR(interp->modules_reloading); } @@ -1794,88 +1785,12 @@ PyObject * PyImport_ReloadModule(PyObject *m) { - PyInterpreterState *interp = PyThreadState_Get()->interp; - PyObject *modules_reloading = interp->modules_reloading; + /* call imp.reload */ + _Py_IDENTIFIER(reload); 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; - } - - 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; -} + PyObject *imp = PyDict_GetItemString(modules, "imp"); + return _PyObject_CallMethodId(imp, &PyId_reload, "O", m); +}; /* Higher-level import emulator which emulates the "import" statement @@ -2171,17 +2086,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 */ @@ -2225,7 +2129,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) {