cpython: eb68502731dd (original) (raw)
Mercurial > cpython
changeset 76640:eb68502731dd
Issues #13959, 14647: Re-implement imp.reload() in Lib/imp.py. Thanks to Eric Snow for the patch. [#13959]
Brett Cannon brett@python.org | |
---|---|
date | Sun, 29 Apr 2012 14:38:11 -0400 |
parents | 1255cac63dfc |
children | 40a05f9eb4c6 |
files | Include/pystate.h Lib/imp.py Objects/moduleobject.c Python/import.c Python/pystate.c Python/pythonrun.c |
diffstat | 6 files changed, 47 insertions(+), 108 deletions(-)[+] [-] Include/pystate.h 1 Lib/imp.py 33 Objects/moduleobject.c 2 Python/import.c 113 Python/pystate.c 2 Python/pythonrun.c 4 |
line wrap: on
line diff
--- a/Include/pystate.h +++ b/Include/pystate.h @@ -26,7 +26,6 @@ typedef struct _is { PyObject *sysdict; PyObject *builtins; PyObject *importlib;
PyObject *codec_search_path; PyObject *codec_search_cache;
--- a/Lib/imp.py +++ b/Lib/imp.py @@ -6,7 +6,7 @@ functionality over this module. """
(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 @@ def find_module(name, path=None): 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):
- """
- if not module or type(module) != type(sys):
raise TypeError("reload() argument must be module")[](#l2.27)
- name = module.name
- if name not in sys.modules:
msg = "module {} not in sys.modules"[](#l2.30)
raise ImportError(msg.format(name), name=name)[](#l2.31)
- if name in _RELOADING:
return _RELOADING[name][](#l2.33)
- _RELOADING[name] = module
- try:
parent_name = name.rpartition('.')[0][](#l2.36)
if parent_name and parent_name not in sys.modules:[](#l2.37)
msg = "parent {!r} not in sys.modules"[](#l2.38)
raise ImportError(msg.format(parentname), name=parent_name)[](#l2.39)
return module.__loader__.load_module(name)[](#l2.40)
- finally:
try:[](#l2.42)
del _RELOADING[name][](#l2.43)
except KeyError:[](#l2.44)
pass[](#l2.45)
--- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -285,7 +285,7 @@ void pos = 0; while (PyDict_Next(d, &pos, &key, &value)) { if (value != Py_None && PyUnicode_Check(key)) {
if (PyUnicode_READ_CHAR(key, 0) == '_' && [](#l3.7)
if (PyUnicode_READ_CHAR(key, 0) == '_' &&[](#l3.8) PyUnicode_READ_CHAR(key, 1) != '_') {[](#l3.9) if (Py_VerboseFlag > 1) {[](#l3.10) const char *s = _PyUnicode_AsString(key);[](#l3.11)
--- a/Python/import.c +++ b/Python/import.c @@ -410,14 +410,6 @@ void #endif } -static void -imp_modules_reloading_clear(void) -{
- PyInterpreterState *interp = PyThreadState_Get()->interp;
- if (interp->modules_reloading != NULL)
PyDict_Clear(interp->modules_reloading);[](#l4.12)
-} - /* Helper for sys */ PyObject * @@ -575,7 +567,6 @@ PyImport_Cleanup(void) PyDict_Clear(modules); interp->modules = NULL; Py_DECREF(modules);
} @@ -1783,87 +1774,23 @@ PyImport_ImportModuleLevel(const char *n 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: "[](#l4.43)
"no modules_reloading dictionary!");[](#l4.44)
return NULL;[](#l4.45)
- PyObject *imp = PyDict_GetItemString(modules, "imp");
- if (imp == NULL) {
imp = PyImport_ImportModule("imp");[](#l4.48)
if (imp == NULL) {[](#l4.49)
return NULL;[](#l4.50)
}[](#l4.51)
- }
- else {
}Py_INCREF(imp);[](#l4.54)
- if (m == NULL || !PyModule_Check(m)) {
PyErr_SetString(PyExc_TypeError,[](#l4.58)
"reload() argument must be module");[](#l4.59)
return NULL;[](#l4.60)
- }
- name = PyModule_GetNameObject(m);
- if (name == NULL || PyUnicode_READY(name) == -1)
return NULL;[](#l4.64)
- if (m != PyDict_GetItem(modules, name)) {
PyErr_Format(PyExc_ImportError,[](#l4.66)
"reload(): module %R not in sys.modules",[](#l4.67)
name);[](#l4.68)
Py_DECREF(name);[](#l4.69)
return NULL;[](#l4.70)
- }
- existing_m = PyDict_GetItem(modules_reloading, name);
- if (existing_m != NULL) {
/* Due to a recursive reload, this module is already[](#l4.74)
being reloaded. */[](#l4.75)
Py_DECREF(name);[](#l4.76)
Py_INCREF(existing_m);[](#l4.77)
return existing_m;[](#l4.78)
- }
- if (PyDict_SetItem(modules_reloading, name, m) < 0) {
Py_DECREF(name);[](#l4.81)
return NULL;[](#l4.82)
- }
- subname_start = PyUnicode_FindChar(name, '.', 0,
PyUnicode_GET_LENGTH(name), -1);[](#l4.86)
- if (subname_start != -1) {
PyObject *parentname, *parent;[](#l4.88)
parentname = PyUnicode_Substring(name, 0, subname_start);[](#l4.89)
if (parentname == NULL) {[](#l4.90)
goto error;[](#l4.91)
}[](#l4.92)
parent = PyDict_GetItem(modules, parentname);[](#l4.93)
Py_XDECREF(parent);[](#l4.94)
if (parent == NULL) {[](#l4.95)
PyErr_Format(PyExc_ImportError,[](#l4.96)
"reload(): parent %R not in sys.modules",[](#l4.97)
parentname);[](#l4.98)
goto error;[](#l4.99)
}[](#l4.100)
- }
- loader = PyObject_GetAttrId(m, &PyId___loader_);
- if (loader == NULL) {
goto error;[](#l4.105)
- }
- newm = _PyObject_CallMethodId(loader, &PyId_load_module, "O", name);
- Py_DECREF(loader);
- if (newm == NULL) {
/* load_module probably removed name from modules because of[](#l4.110)
* the error. Put back the original module object. We're[](#l4.111)
* going to return NULL in this case regardless of whether[](#l4.112)
* replacing name succeeds, so the return value is ignored.[](#l4.113)
*/[](#l4.114)
PyDict_SetItem(modules, name, m);[](#l4.115)
- }
- reloaded_module = _PyObject_CallMethodId(imp, &PyId_reload, "O", m);
- Py_DECREF(imp);
- return reloaded_module;
} @@ -2160,17 +2087,6 @@ imp_load_dynamic(PyObject self, PyObjec #endif / HAVE_DYNAMIC_LOADING */ -static PyObject * -imp_reload(PyObject *self, PyObject *v) -{
-} - -PyDoc_STRVAR(doc_reload, -"reload(module) -> module\n[](#l4.139) -\n[](#l4.140) -Reload the module. The module must have been successfully imported before."); - /* Doc strings */ @@ -2214,7 +2130,6 @@ static PyMethodDef imp_methods[] = { {"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},
--- a/Python/pystate.c +++ b/Python/pystate.c @@ -69,7 +69,6 @@ PyInterpreterState_New(void) Py_FatalError("Can't initialize threads for interpreter"); #endif interp->modules = NULL;
interp->modules_reloading = NULL;[](#l5.7) interp->modules_by_index = NULL;[](#l5.8) interp->sysdict = NULL;[](#l5.9) interp->builtins = NULL;[](#l5.10)
@@ -114,7 +113,6 @@ PyInterpreterState_Clear(PyInterpreterSt 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);
--- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -314,9 +314,6 @@ Py_InitializeEx(int install_sigs) 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");[](#l6.9)
/* Init Unicode implementation; relies on the codec registry */ if (_PyUnicode_Init() < 0) @@ -680,7 +677,6 @@ Py_NewInterpreter(void) /* XXX The following is lax in error checking */ interp->modules = PyDict_New();
bimod = _PyImport_FindBuiltin("builtins"); if (bimod != NULL) {