Merge pull request #1307 from campagnola/acq4-merge
Fix reload to use mod.__cache__ to get name of pyc files
This commit is contained in:
commit
51bb8b9bb8
@ -34,42 +34,72 @@ py3 = sys.version_info >= (3,)
|
||||
|
||||
|
||||
def reloadAll(prefix=None, debug=False):
|
||||
"""Automatically reload everything whose __file__ begins with prefix.
|
||||
- Skips reload if the file has not been updated (if .pyc is newer than .py)
|
||||
- if prefix is None, checks all loaded modules
|
||||
"""Automatically reload all modules whose __file__ begins with *prefix*.
|
||||
|
||||
Skips reload if the file has not been updated (if .pyc is newer than .py)
|
||||
If *prefix* is None, then all loaded modules are checked.
|
||||
|
||||
Returns a dictionary {moduleName: (reloaded, reason)} describing actions taken
|
||||
for each module.
|
||||
"""
|
||||
failed = []
|
||||
changed = []
|
||||
ret = {}
|
||||
for modName, mod in list(sys.modules.items()): ## don't use iteritems; size may change during reload
|
||||
if not inspect.ismodule(mod):
|
||||
ret[modName] = (False, 'not a module')
|
||||
continue
|
||||
if modName == '__main__':
|
||||
ret[modName] = (False, 'ignored __main__')
|
||||
continue
|
||||
|
||||
## Ignore if the file name does not start with prefix
|
||||
if not hasattr(mod, '__file__') or mod.__file__ is None or os.path.splitext(mod.__file__)[1] not in ['.py', '.pyc']:
|
||||
# Ignore modules without a __file__ that is .py or .pyc
|
||||
if getattr(mod, '__file__', None) is None:
|
||||
ret[modName] = (False, 'module has no __file__')
|
||||
continue
|
||||
|
||||
if os.path.splitext(mod.__file__)[1] not in ['.py', '.pyc']:
|
||||
ret[modName] = (False, '%s not a .py/pyc file' % str(mod.__file__))
|
||||
continue
|
||||
|
||||
# Ignore if the file name does not start with prefix
|
||||
if prefix is not None and mod.__file__[:len(prefix)] != prefix:
|
||||
ret[modName] = (False, 'file %s not in prefix %s' % (mod.__file__, prefix))
|
||||
continue
|
||||
|
||||
## ignore if the .pyc is newer than the .py (or if there is no pyc or py)
|
||||
py = os.path.splitext(mod.__file__)[0] + '.py'
|
||||
pyc = py + 'c'
|
||||
if py not in changed and os.path.isfile(pyc) and os.path.isfile(py) and os.stat(pyc).st_mtime >= os.stat(py).st_mtime:
|
||||
#if debug:
|
||||
#print "Ignoring module %s; unchanged" % str(mod)
|
||||
if py in changed:
|
||||
# already processed this module
|
||||
continue
|
||||
changed.append(py) ## keep track of which modules have changed to insure that duplicate-import modules get reloaded.
|
||||
if not os.path.isfile(py):
|
||||
# skip modules that lie about their __file__
|
||||
ret[modName] = (False, '.py does not exist: %s' % py)
|
||||
continue
|
||||
|
||||
# if source file is newer than cache file, then it needs to be reloaded.
|
||||
pyc = getattr(mod, '__cached__', py + 'c')
|
||||
|
||||
if os.path.isfile(pyc) and os.stat(pyc).st_mtime < os.stat(py).st_mtime:
|
||||
ret[modName] = (False, 'code has not changed since compile')
|
||||
continue
|
||||
|
||||
# keep track of which modules have changed to ensure that duplicate-import modules get reloaded.
|
||||
changed.append(py)
|
||||
|
||||
try:
|
||||
reload(mod, debug=debug)
|
||||
except:
|
||||
ret[modName] = (True, None)
|
||||
except Exception as exc:
|
||||
printExc("Error while reloading module %s, skipping\n" % mod)
|
||||
failed.append(mod.__name__)
|
||||
ret[modName] = (False, 'reload failed: %s' % traceback.format_exception_only(type(exc), exc))
|
||||
|
||||
if len(failed) > 0:
|
||||
raise Exception("Some modules failed to reload: %s" % ', '.join(failed))
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def reload(module, debug=False, lists=False, dicts=False):
|
||||
"""Replacement for the builtin reload function:
|
||||
- Reloads the module as usual
|
||||
|
@ -62,11 +62,10 @@ def test_reload():
|
||||
v1 = (reload_test_mod.C, reload_test_mod.C.sig, reload_test_mod.C.fn, reload_test_mod.C.fn.__func__, c.sig, c.fn, c.fn.__func__)
|
||||
|
||||
|
||||
|
||||
# write again and reload
|
||||
open(mod, 'w').write(code.format(path_repr=pgpath_repr, msg="C.fn() Version2"))
|
||||
remove_cache(mod)
|
||||
pg.reload.reloadAll(path, debug=True)
|
||||
result1 = pg.reload.reloadAll(path, debug=True)
|
||||
if py3:
|
||||
v2 = (reload_test_mod.C, reload_test_mod.C.sig, reload_test_mod.C.fn, c.sig, c.fn, c.fn.__func__)
|
||||
else:
|
||||
@ -90,7 +89,7 @@ def test_reload():
|
||||
# write again and reload
|
||||
open(mod, 'w').write(code.format(path_repr=pgpath_repr, msg="C.fn() Version2"))
|
||||
remove_cache(mod)
|
||||
pg.reload.reloadAll(path, debug=True)
|
||||
result2 = pg.reload.reloadAll(path, debug=True)
|
||||
if py3:
|
||||
v3 = (reload_test_mod.C, reload_test_mod.C.sig, reload_test_mod.C.fn, c.sig, c.fn, c.fn.__func__)
|
||||
else:
|
||||
|
Loading…
Reference in New Issue
Block a user