summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Wouters <thomas@python.org>2006-03-27 12:50:42 (GMT)
committerThomas Wouters <thomas@python.org>2006-03-27 12:50:42 (GMT)
commitc47bfb0874a2184fc156861a659ea426967ebc19 (patch)
treeedd0fe0e3cc32eb5509159e5a4916342e5670d22
parenta8de08daefd6a10f952f57f9969e393220f890c1 (diff)
downloadcpython-c47bfb0874a2184fc156861a659ea426967ebc19.zip
cpython-c47bfb0874a2184fc156861a659ea426967ebc19.tar.gz
cpython-c47bfb0874a2184fc156861a659ea426967ebc19.tar.bz2
Backport Ka-Ping Yee's trunk checkin r41400:
Fix SF bug #417833 (pydoc HTTP reload failure) by removing from sys.modules all submodules of a the given module/package path when trying to reload a module.
-rwxr-xr-xLib/pydoc.py30
1 files changed, 17 insertions, 13 deletions
diff --git a/Lib/pydoc.py b/Lib/pydoc.py
index fca4e09..19c37ed 100755
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -249,20 +249,24 @@ def safeimport(path, forceload=0, cache={}):
package path is specified, the module at the end of the path is returned,
not the package at the beginning. If the optional 'forceload' argument
is 1, we reload the module from disk (unless it's a dynamic extension)."""
- if forceload and path in sys.modules:
- # This is the only way to be sure. Checking the mtime of the file
- # isn't good enough (e.g. what if the module contains a class that
- # inherits from another module that has changed?).
- if path not in sys.builtin_module_names:
- # Python never loads a dynamic extension a second time from the
- # same path, even if the file is changed or missing. Deleting
- # the entry in sys.modules doesn't help for dynamic extensions,
- # so we're not even going to try to keep them up to date.
- info = inspect.getmoduleinfo(sys.modules[path].__file__)
- if info[3] != imp.C_EXTENSION:
- cache[path] = sys.modules[path] # prevent module from clearing
- del sys.modules[path]
try:
+ # If forceload is 1 and the module has been previously loaded from
+ # disk, we always have to reload the module. Checking the file's
+ # mtime isn't good enough (e.g. the module could contain a class
+ # that inherits from another module that has changed).
+ if forceload and path in sys.modules:
+ if path not in sys.builtin_module_names:
+ # Avoid simply calling reload() because it leaves names in
+ # the currently loaded module lying around if they're not
+ # defined in the new source file. Instead, remove the
+ # module from sys.modules and re-import. Also remove any
+ # submodules because they won't appear in the newly loaded
+ # module's namespace if they're already in sys.modules.
+ subs = [m for m in sys.modules if m.startswith(path + '.')]
+ for key in [path] + subs:
+ # Prevent garbage collection.
+ cache[key] = sys.modules[key]
+ del sys.modules[key]
module = __import__(path)
except:
# Did the error occur before or after the module was found?