durusmail: quixote-users: Re: rtemplate: utility for reloading changed PTL files
rtemplate: utility for reloading changed PTL files
2003-12-06
Re: rtemplate: utility for reloading changed PTL files
2003-12-06
2003-12-06
2003-12-06
2003-12-06
Re: rtemplate: utility for reloading changed PTL files
2003-12-07
Re: rtemplate: utility for reloading changed PTL files
2003-12-07
Re: rtemplate: utility for reloading changed PTL files
2003-12-08
2003-12-07
2003-12-08
2003-12-06
Re: rtemplate: utility for reloading changed PTL files
2003-12-08
Re: rtemplate: utility for reloading changed PTLfiles
2003-12-08
2003-12-08
Re: rtemplate: utility for reloading changed PTL files
Graham Fawcett
2003-12-06
Here's a slightly less crufty version of rtemplate.py: removed a print
statement and a useless attribute assignment.

-- g

"""
rtemplate -- support for reloading changed PTL files (to aid debugging)
Graham Fawcett 
2003.12.06 -- first revision.
"""

from quixote.ptl_compile import compile_template
import os
import sys
import time


class Reloadable:
    """
    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 module.

    Seems to work for normal Python modules as well.
    """

    def __init__(self, module):
        self.filename = module.__file__
        self.name = module.__name__
        self.module = module.__dict__
        self.mtime = self._get_mtime()

    def _get_mtime(self):
        mt = os.stat(self.filename).st_mtime
        return mt

    def __getattr__(self, name):
        mtime = self._get_mtime()
        if mtime > self.mtime:
            self.mtime = mtime
            self._reload()
        try:
            return self.module[name]
        except KeyError, msg:
            raise AttributeError, msg

    def _reload(self):
        print >> sys.stderr, '%s: Reloading %s' % (time.ctime(), self.name)
        f = open(self.filename)
        try:
            codeobj = compile_template(f, self.filename)
            m = {}
            m['__name__'] = self.name
            m['__file__'] = self.filename
            exec codeobj in m
        finally:
            f.close()
        self.module = m

reply