Skip Montanaro wrote: > >> I would rename the module to quixote.reloadable. (A module that > >> provides one primary class should be named after that class.) > >> (Although arguably the class could be better named: Reloader? > >> ReloadProxy?) > > Graham> Yes, I'm not sure either. Originally it was ReloadableTemplate > Graham> (hence the module name, rtemplate), but that's not really > Graham> accurate either. I like Reloader, but perhaps it should be > Graham> something more specific to modules? > > How about ReloadableModule (or ModuleReloader or ModuleAutoloader)? That's > what it is, after all. I think I like ReloadableModule. I guess quixote.reloadable_module would be the most accurate name for the module, though it's a bit long. If Neil et. al. want to include it in Quixote, they are welcome to modify the names as they please. Attached is a renamed version with Greg's suggested doc changes. I also munged some of the attribute/method names, to reduce the chances that names in the proxy might be shadowing names in the target module. > Are there other objects besides modules for which it > can serve as a proxy? As written, I can't think of any; it expects a source file, and compiles it; that pretty much eliminates anything but modules. Regards, -- Graham
""" reloadable_module support for reloading changed PTL files (to aid debugging) Graham Fawcett2003.12.06 -- first revision. 2003.12.07 -- added warnings to documentation, adjusted attribute names to reduce possible namespace collisions """ from quixote.ptl_compile import compile_template import os import sys import time class ReloadableModule: """ A module proxy that reloads itself when its source file changes. The constructor takes an already-loaded PTL module, and acts as a proxy for that module. If the module's source changes, this class will recompile the PTL file and replace its copy of the original module with the modified one. Uses Quixote's ptl_compile module, which requires the Python compiler package. It seems to work for normal Python modules as well as PTL modules. This class is intended only as a debugging aid. Reloading modules can occasionally lead to unexpected behaviour, and is not guaranteed to work with all possible modules. Example usage:: # ---- main.ptl ---- from quixote.reloadable_module import ReloadableModule import buggy # load the module once buggy = ReloadableModule(buggy) # wrap it in a reloader _q_exports = ['buggy', ... ] """ def __init__(self, module): self._rm_filename = module.__file__ self._rm_name = module.__name__ self._rm_module = module.__dict__ self._rm_mtime = self._rm_get_mtime() def _rm_get_mtime(self): mt = os.stat(self._rm_filename).st_mtime return mt def __getattr__(self, name): mtime = self._rm_get_mtime() if mtime > self._rm_mtime: self._rm_mtime = mtime self._rm_reload() try: return self._rm_module[name] except KeyError, msg: raise AttributeError, msg def _rm_reload(self): print >> sys.stderr, '%s: Reloading %s' % (time.ctime(), self._rm_name) f = open(self._rm_filename) try: codeobj = compile_template(f, self._rm_filename) m = {} m['__name__'] = self._rm_name m['__file__'] = self._rm_filename exec codeobj in m finally: f.close() self._rm_module = m