PKӤ2L`Z Cheetah/CacheRegion.py# $Id: CacheRegion.py,v 1.1 2005/07/10 18:38:39 tavis_rudd Exp $ """Cache holder classes for Cheetah: Cache regions are defined using the #cache Cheetah directive. Each cache region can be viewed as a dictionnary (keyed by cacheID) handling at least one cache (the default one). It's possible to add caches in a region by using the `varyBy` #cache directive parameter as in the following example:: #cache varyBy=$getArticleID() #def getArticle this is the article content. #end def #end cache The code above will generate a CacheRegion, and depending on the article id value, add some new sub-caches ad-hoc. Meta-Data ================================================================================ Author: Philippe Normand Version: $Revision: 1.1 $ Start Date: 2005/06/20 Last Revision Date: $Date: 2005/07/10 18:38:39 $ """ __author__ = "Philippe Normand " __revision__ = "$Revision: 1.1 $"[11:-2] import md5 class CacheRegion: """ A `CacheRegion` stores some `Cache` instances. """ def __init__(self): self.clear() def clear(self): " drop all the caches stored in this cache region " self.caches = {} def getCache(self, cacheID): """ Lazy access to a cache Try to find a cache in the stored caches. If it doesn't exist, it's created. Returns a `Cache` instance. """ cacheID = md5.new(str(cacheID)).hexdigest() if not self.caches.has_key(cacheID): cache = Cache(cacheID) self.caches[cacheID] = cache return self.caches.get(cacheID) class Cache: """ Cache class. A Cache is a container storing: - cacheID (string) - refreshTime (timestamp or None) : last time the cache was refreshed - data (string) : the content of the cache """ def __init__(self, cacheID): self.setID(cacheID) self.clear() def clear(self): self.setData("") self.setRefreshTime(None) def getID(self): return self.cacheID def setID(self, cacheID): self.cacheID = cacheID def setData(self, data): self.data = data def getData(self): return self.data def setRefreshTime(self, time): self.refreshTime = time def getRefreshTime(self): return self.refreshTime PKt95y'OOCheetah/CacheRegion.pyc; /kBc@sLdZdZddd!ZdkZdfdYZdfd YZdS( s#Cache holder classes for Cheetah: Cache regions are defined using the #cache Cheetah directive. Each cache region can be viewed as a dictionnary (keyed by cacheID) handling at least one cache (the default one). It's possible to add caches in a region by using the `varyBy` #cache directive parameter as in the following example:: #cache varyBy=$getArticleID() #def getArticle this is the article content. #end def #end cache The code above will generate a CacheRegion, and depending on the article id value, add some new sub-caches ad-hoc. Meta-Data ================================================================================ Author: Philippe Normand Version: $Revision: 1.1 $ Start Date: 2005/06/20 Last Revision Date: $Date: 2005/07/10 18:38:39 $ s$Philippe Normand s$Revision: 1.1 $i iNs CacheRegioncBs)tZdZdZdZdZRS(s4 A `CacheRegion` stores some `Cache` instances. cCs|idS(N(sselfsclear(sself((s8build/bdist.darwin-8.7.1-i386/egg/Cheetah/CacheRegion.pys__init__#scCs h|_dS(s1 drop all the caches stored in this cache region N(sselfscaches(sself((s8build/bdist.darwin-8.7.1-i386/egg/Cheetah/CacheRegion.pysclear&scCs`tit|i}|ii| ot|}||i| and Mike Orr Version: $Revision: 1.18 $ Start Date: 2001/03/30 Last Revision Date: $Date: 2005/01/03 19:57:24 $ """ __author__ = "Tavis Rudd and Mike Orr " __revision__ = "$Revision: 1.18 $"[11:-2] import getopt, glob, os, pprint, re, shutil, sys import cPickle as pickle from Cheetah.Version import Version from Cheetah.Compiler import Compiler from Cheetah.Template import Template from Cheetah.Utils.Misc import mkdirsWithPyInitFiles from Cheetah.Utils.optik import OptionParser optionDashesRE = re.compile( R"^-{1,2}" ) moduleNameRE = re.compile( R"^[a-zA-Z_][a-zA-Z_0-9]*$" ) def fprintfMessage(stream, format, *args): if format[-1:] == '^': format = format[:-1] else: format += '\n' if args: message = format % args else: message = format stream.write(message) class Error(Exception): pass class Bundle: """Wrap the source, destination and backup paths in one neat little class. Used by CheetahWrapper.getBundles(). """ def __init__(self, **kw): self.__dict__.update(kw) def __repr__(self): return "" % self.__dict__ class MyOptionParser(OptionParser): standard_option_list = [] # We use commands for Optik's standard options. def error(self, msg): """Print our usage+error page.""" usage(HELP_PAGE2, msg) def print_usage(self, file=None): """Our usage+error page already has this.""" pass ################################################## ## USAGE FUNCTION & MESSAGES def usage(usageMessage, errorMessage="", out=sys.stderr): """Write help text, an optional error message, and abort the program. """ out.write(WRAPPER_TOP) out.write(usageMessage) exitStatus = 0 if errorMessage: out.write('\n') out.write("*** USAGE ERROR ***: %s\n" % errorMessage) exitStatus = 1 sys.exit(exitStatus) WRAPPER_TOP = """\ __ ____________ __ \ \/ \/ / \/ * * \/ CHEETAH %(Version)s Command-Line Tool \ | / \ ==----== / by Tavis Rudd \__________/ and Mike Orr """ % globals() HELP_PAGE1 = """\ USAGE: ------ cheetah compile [options] [FILES ...] : Compile template definitions cheetah fill [options] [FILES ...] : Fill template definitions cheetah help : Print this help message cheetah options : Print options help message cheetah test [options] : Run Cheetah's regression tests : (same as for unittest) cheetah version : Print Cheetah version number You may abbreviate the command to the first letter; e.g., 'h' == 'help'. If FILES is a single "-", read standard input and write standard output. Run "cheetah options" for the list of valid options. """ HELP_PAGE2 = """\ OPTIONS FOR "compile" AND "fill": --------------------------------- --idir DIR, --odir DIR : input/output directories (default: current dir) --iext EXT, --oext EXT : input/output filename extensions (default for compile: tmpl/py, fill: tmpl/html) -R : recurse subdirectories looking for input files --debug : print lots of diagnostic output to standard error --env : put the environment in the searchList --flat : no destination subdirectories --nobackup : don't make backups --pickle FILE : unpickle FILE and put that object in the searchList --stdout, -p : output to standard output (pipe) Run "cheetah help" for the main help screen. """ ################################################## ## CheetahWrapper CLASS class CheetahWrapper: MAKE_BACKUPS = True BACKUP_SUFFIX = ".bak" def __init__(self): self.progName = None self.command = None self.opts = None self.files = None self.sourceFiles = [] self.searchList = [] ################################################## ## VERBOSITY METHODS def chatter(self, format, *args): """Print a verbose message to stdout. But don't if .opts.stdout is true or .opts.verbose is false. """ if self.opts.stdout or not self.opts.verbose: return fprintfMessage(sys.stdout, format, *args) def debug(self, format, *args): """Print a debugging message to stderr, but don't if .debug is false. """ if self.opts.debug: fprintfMessage(sys.stderr, format, *args) def warn(self, format, *args): """Always print a warning message to stderr. """ fprintfMessage(sys.stderr, format, *args) ################################################## ## HELPER METHODS def _fixExts(self): assert self.opts.oext, "oext is empty!" iext, oext = self.opts.iext, self.opts.oext if iext and not iext.startswith("."): self.opts.iext = "." + iext if oext and not oext.startswith("."): self.opts.oext = "." + oext def parseOpts(self, args): C, D, W = self.chatter, self.debug, self.warn self.isCompile = isCompile = self.command[0] == 'c' defaultOext = isCompile and ".py" or ".html" parser = MyOptionParser() pao = parser.add_option pao("--idir", action="store", dest="idir", default="") pao("--odir", action="store", dest="odir", default="") pao("--iext", action="store", dest="iext", default=".tmpl") pao("--oext", action="store", dest="oext", default=defaultOext) pao("-R", action="store_true", dest="recurse", default=False) pao("--stdout", "-p", action="store_true", dest="stdout", default=False) pao("--debug", action="store_true", dest="debug", default=False) pao("--env", action="store_true", dest="env", default=False) pao("--pickle", action="store", dest="pickle", default="") pao("--flat", action="store_true", dest="flat", default=False) pao("--nobackup", action="store_true", dest="nobackup", default=False) self.opts, self.files = opts, files = parser.parse_args(args) D("""\ cheetah compile %s Options are %s Files are %s""", args, pprint.pformat(vars(opts)), files) self._fixExts() if opts.env: self.searchList.append(os.environ) if opts.pickle: f = open(opts.pickle, 'rb') unpickled = pickle.load(f) f.close() self.searchList.append(unpickled) opts.verbose = not opts.stdout def compileOrFillStdin(self): if self.isCompile: output = Compiler(file=sys.stdin) else: output = Template(file=sys.stdin) output = str(output) sys.stdout.write(output) def compileOrFillBundle(self, b): C, D, W = self.chatter, self.debug, self.warn src = b.src dst = b.dst base = b.base basename = b.basename dstDir = os.path.dirname(dst) what = self.isCompile and "Compiling" or "Filling" C("%s %s -> %s^", what, src, dst) # No trailing newline. if os.path.exists(dst) and not self.opts.nobackup: bak = b.bak C(" (backup %s)", bak) # On same line as previous message. else: bak = None C("") if self.isCompile: if not moduleNameRE.match(basename): tup = basename, src raise Error("""\ %s: base name %s contains invalid characters. It must be named according to the same rules as Python modules.""" % tup) obj = Compiler(file=src, \ moduleName=basename, mainClassName=basename) else: obj = Template(file=src, searchList=self.searchList) output = str(obj) if bak: shutil.copyfile(dst, bak) if dstDir and not os.path.exists(dstDir): if self.isCompile: mkdirsWithPyInitFiles(dstDir) else: os.makedirs(dstDir) if self.opts.stdout: sys.stdout.write(output) else: f = open(dst, 'w') f.write(output) f.close() def _checkForCollisions(self, bundles): """Check for multiple source paths writing to the same destination path. """ C, D, W = self.chatter, self.debug, self.warn isError = False dstSources = {} for b in bundles: if dstSources.has_key(b.dst): dstSources[b.dst].append(b.src) else: dstSources[b.dst] = [b.src] keys = dstSources.keys() keys.sort() for dst in keys: sources = dstSources[dst] if len(sources) > 1: isError = True sources.sort() fmt = \ "Collision: multiple source files %s map to one destination file %s" W(fmt, sources, dst) if isError: what = self.isCompile and "Compilation" or "Filling" sys.exit("%s aborted due to collisions" % what) def getBundles(self, sourceFiles): flat = self.opts.flat idir = self.opts.idir iext = self.opts.iext nobackup = self.opts.nobackup odir = self.opts.odir oext = self.opts.oext idirSlash = idir + os.sep bundles = [] for src in sourceFiles: # 'base' is the subdirectory plus basename. base = src if idir and src.startswith(idirSlash): base = src[len(idirSlash):] if iext and base.endswith(iext): base = base[:-len(iext)] basename = os.path.basename(base) if flat: dst = os.path.join(odir, basename + oext) else: dbn = basename if odir and base.startswith(os.sep): odd = odir while odd != '': i = base.find(odd) if i == 0: dbn = base[len(odd):] if dbn[0] == '/': dbn = dbn[1:] break odd = os.path.dirname(odd) if odd == '/': break dst = os.path.join(odir, dbn + oext) else: dst = os.path.join(odir, base + oext) bak = dst + self.BACKUP_SUFFIX b = Bundle(src=src, dst=dst, bak=bak, base=base, basename=basename) bundles.append(b) return bundles def _expandSourceFilesWalk(self, arg, dir, files): """Recursion extension for .expandSourceFiles(). This method is a callback for os.path.walk(). 'arg' is a list to which successful paths will be appended. """ iext = self.opts.iext for fil in files: path = os.path.join(dir, fil) if path.endswith(iext) and os.path.isfile(path): arg.append(path) elif os.path.islink(path) and os.path.isdir(path): os.path.walk(path, self._expandSourceFilesWalk, arg) # If is directory, do nothing; 'walk' will eventually get it. def expandSourceFiles(self, files, recurse, addIextIfMissing): """Calculate source paths from 'files' by applying the command-line options. """ C, D, W = self.chatter, self.debug, self.warn idir = self.opts.idir iext = self.opts.iext ret = [] for fil in self.files: oldRetLen = len(ret) D("Expanding %s", fil) path = os.path.join(idir, fil) pathWithExt = path + iext # May or may not be valid. if os.path.isdir(path): if recurse: os.path.walk(path, self._expandSourceFilesWalk, ret) else: raise Error("source file '%s' is a directory" % path) elif os.path.isfile(path): ret.append(path) elif addIextIfMissing and not path.endswith(iext) and \ os.path.isfile(pathWithExt): ret.append(pathWithExt) # Do not recurse directories discovered by iext appending. elif os.path.exists(path): W("Skipping source file '%s', not a plain file.", path) else: W("Skipping source file '%s', not found.", path) if len(ret) > oldRetLen: D(" ... found %s", ret[oldRetLen:]) return ret def compileOrFill(self): C, D, W = self.chatter, self.debug, self.warn opts, files = self.opts, self.files if files == ["-"]: self.compileOrFillStdin() return elif not files and opts.recurse: which = opts.idir and "idir" or "current" C("Drilling down recursively from %s directory.", which) sourceFiles = [] dir = os.path.join(self.opts.idir, os.curdir) os.path.walk(dir, self._expandSourceFilesWalk, sourceFiles) elif not files: usage(HELP_PAGE1, "Neither files nor -R specified!") else: sourceFiles = self.expandSourceFiles(files, opts.recurse, True) sourceFiles = [os.path.normpath(x) for x in sourceFiles] D("All source files found: %s", sourceFiles) bundles = self.getBundles(sourceFiles) D("All bundles: %s", pprint.pformat(bundles)) if self.opts.flat: self._checkForCollisions(bundles) for b in bundles: self.compileOrFillBundle(b) ################################################## ## COMMAND METHODS def compile(self): self.compileOrFill() def fill(self): self.compileOrFill() def help(self): usage(HELP_PAGE1, "", sys.stdout) def options(self): usage(HELP_PAGE2, "", sys.stdout) def test(self): # @@MO: Ugly kludge. TEST_WRITE_FILENAME = 'cheetah_test_file_creation_ability.tmp' try: f = open(TEST_WRITE_FILENAME, 'w') except: sys.exit("""\ Cannot run the tests because you don't have write permission in the current directory. The tests need to create temporary files. Change to a directory you do have write permission to and re-run the tests.""") else: f.close() os.remove(TEST_WRITE_FILENAME) # @@MO: End ugly kludge. from Cheetah.Tests import Test import Cheetah.Tests.unittest_local_copy as unittest del sys.argv[1:] # Prevent unittest from misinterpreting options. sys.argv.extend(self.testOpts) #unittest.main(testSuite=Test.testSuite) #unittest.main(testSuite=Test.testSuite) unittest.main(module=Test) def version(self): print Version # If you add a command, also add it to the 'meths' variable in main(). ################################################## ## MAIN ROUTINE def main(self, argv=None): """The main program controller.""" if argv is None: argv = sys.argv # Step 1: Determine the command and arguments. try: self.progName = progName = os.path.basename(argv[0]) self.command = command = optionDashesRE.sub("", argv[1]) if command == 'test': self.testOpts = argv[2:] else: self.parseOpts(argv[2:]) except IndexError: usage(HELP_PAGE1, "not enough command-line arguments") # Step 2: Call the command meths = (self.compile, self.fill, self.help, self.options, self.test, self.version) for meth in meths: methName = meth.__name__ # Or meth.im_func.func_name # Or meth.func_name (Python >= 2.1 only, sometimes works on 2.0) methInitial = methName[0] if command in (methName, methInitial): sys.argv[0] += (" " + methName) # @@MO: I don't necessarily agree sys.argv[0] should be # modified. meth() return # If none of the commands matched. usage(HELP_PAGE1, "unknown command '%s'" % command) #run = main ################################################## ## if run from the command line if __name__ == '__main__': CheetahWrapper().main() # vim: shiftwidth=4 tabstop=4 expandtab PKt95SSCheetah/CheetahWrapper.pyc; Ac@shdZdZddd!ZdkZdkZdkZdkZdkZdkZdk Z dk Z dk l Z dklZdklZd klZd klZeid Zeid Zd ZdefdYZdfdYZdefdYZde idZde Z!dZ"dZ#dfdYZ$e%djoe$i&ndS(sCheetah command-line interface. 2002-09-03 MSO: Total rewrite. 2002-09-04 MSO: Bugfix, compile command was using wrong output ext. 2002-11-08 MSO: Another rewrite. Meta-Data ================================================================================ Author: Tavis Rudd and Mike Orr Version: $Revision: 1.18 $ Start Date: 2001/03/30 Last Revision Date: $Date: 2005/01/03 19:57:24 $ s@Tavis Rudd and Mike Orr s$Revision: 1.18 $i iN(sVersion(sCompiler(sTemplate(smkdirsWithPyInitFiles(s OptionParsers^-{1,2}s^[a-zA-Z_][a-zA-Z_0-9]*$cGsU|ddjo|d }n |d7}|o||}n|}|i|dS(Nis^s (sformatsargssmessagesstreamswrite(sstreamsformatsargssmessage((s;build/bdist.darwin-8.7.1-i386/egg/Cheetah/CheetahWrapper.pysfprintfMessages sErrorcBstZRS(N(s__name__s __module__(((s;build/bdist.darwin-8.7.1-i386/egg/Cheetah/CheetahWrapper.pysError*ssBundlecBs tZdZdZdZRS(sxWrap the source, destination and backup paths in one neat little class. Used by CheetahWrapper.getBundles(). cKs|ii|dS(N(sselfs__dict__supdateskw(sselfskw((s;build/bdist.darwin-8.7.1-i386/egg/Cheetah/CheetahWrapper.pys__init__2scCsd|iSdS(Ns (sselfs__dict__(sself((s;build/bdist.darwin-8.7.1-i386/egg/Cheetah/CheetahWrapper.pys__repr__5s(s__name__s __module__s__doc__s__init__s__repr__(((s;build/bdist.darwin-8.7.1-i386/egg/Cheetah/CheetahWrapper.pysBundle.s  sMyOptionParsercBs#tZgZdZedZRS(NcCstt|dS(sPrint our usage+error page.N(susages HELP_PAGE2smsg(sselfsmsg((s;build/bdist.darwin-8.7.1-i386/egg/Cheetah/CheetahWrapper.pyserror<scCsdS(s&Our usage+error page already has this.N((sselfsfile((s;build/bdist.darwin-8.7.1-i386/egg/Cheetah/CheetahWrapper.pys print_usage@s(s__name__s __module__sstandard_option_listserrorsNones print_usage(((s;build/bdist.darwin-8.7.1-i386/egg/Cheetah/CheetahWrapper.pysMyOptionParser9s scCs`|it|i|d}|o(|id|id|d}nti|dS(sGWrite help text, an optional error message, and abort the program. is s*** USAGE ERROR ***: %s iN(soutswrites WRAPPER_TOPs usageMessages exitStatuss errorMessagessyssexit(s usageMessages errorMessagesouts exitStatus((s;build/bdist.darwin-8.7.1-i386/egg/Cheetah/CheetahWrapper.pysusageHs    s2 __ ____________ __ \ \/ \/ / \/ * * \/ CHEETAH %(Version)s Command-Line Tool \ | / \ ==----== / by Tavis Rudd \__________/ and Mike Orr sUSAGE: ------ cheetah compile [options] [FILES ...] : Compile template definitions cheetah fill [options] [FILES ...] : Fill template definitions cheetah help : Print this help message cheetah options : Print options help message cheetah test [options] : Run Cheetah's regression tests : (same as for unittest) cheetah version : Print Cheetah version number You may abbreviate the command to the first letter; e.g., 'h' == 'help'. If FILES is a single "-", read standard input and write standard output. Run "cheetah options" for the list of valid options. sOPTIONS FOR "compile" AND "fill": --------------------------------- --idir DIR, --odir DIR : input/output directories (default: current dir) --iext EXT, --oext EXT : input/output filename extensions (default for compile: tmpl/py, fill: tmpl/html) -R : recurse subdirectories looking for input files --debug : print lots of diagnostic output to standard error --env : put the environment in the searchList --flat : no destination subdirectories --nobackup : don't make backups --pickle FILE : unpickle FILE and put that object in the searchList --stdout, -p : output to standard output (pipe) Run "cheetah help" for the main help screen. sCheetahWrappercBstZeZdZdZdZdZdZdZ dZ dZ d Z d Z d Zd Zd ZdZdZdZdZdZdZdZedZRS(Ns.bakcCs:t|_t|_t|_t|_g|_g|_dS(N(sNonesselfsprogNamescommandsoptssfiless sourceFiless searchList(sself((s;build/bdist.darwin-8.7.1-i386/egg/Cheetah/CheetahWrapper.pys__init__s      cGs:|iip |ii odSntti||dS(stPrint a verbose message to stdout. But don't if .opts.stdout is true or .opts.verbose is false. N(sselfsoptssstdoutsverbosesfprintfMessagessyssformatsargs(sselfsformatsargs((s;build/bdist.darwin-8.7.1-i386/egg/Cheetah/CheetahWrapper.pyschatterscGs(|iiotti||ndS(sVPrint a debugging message to stderr, but don't if .debug is false. N(sselfsoptssdebugsfprintfMessagessyssstderrsformatsargs(sselfsformatsargs((s;build/bdist.darwin-8.7.1-i386/egg/Cheetah/CheetahWrapper.pysdebugs cGstti||dS(s2Always print a warning message to stderr. N(sfprintfMessagessyssstderrsformatsargs(sselfsformatsargs((s;build/bdist.darwin-8.7.1-i386/egg/Cheetah/CheetahWrapper.pyswarnscCs|iip td|ii|iif\}}|o|id od||i_n|o|id od||i_ndS(Nsoext is empty!s.(sselfsoptssoextsAssertionErrorsiexts startswith(sselfsoextsiext((s;build/bdist.darwin-8.7.1-i386/egg/Cheetah/CheetahWrapper.pys_fixExtss c Csd|i|i|if\}}} |iddj|_}|odpd}t }|i } | ddddd d d | d dddd d d | dddddd d| dddddd || dddddd t| ddddddd t| dddddd t| dddddd t| dddddd d | ddddd d t| d!dddd"d t|i|\|_|_\} }|d#|tit| ||i| io|iitin| io?t| id$}ti|} |i!|ii| n| i" | _#dS(%Niscs.pys.htmls--idirsactionsstoresdestsidirsdefaultss--odirsodirs--iextsiexts.tmpls--oextsoexts-Rs store_truesrecurses--stdouts-psstdouts--debugsdebugs--envsenvs--picklespickles--flatsflats --nobackupsnobackups.cheetah compile %s Options are %s Files are %ssrb($sselfschattersdebugswarnsCsDsWscommands isCompiles defaultOextsMyOptionParsersparsers add_optionspaosFalses parse_argssargssoptssfilesspprintspformatsvarss_fixExtssenvs searchListsappendsossenvironspicklesopensfsloads unpickledsclosesstdoutsverbose( sselfsargssfilessCsparsersDs isCompilesfs defaultOextsoptssWs unpickledspao((s;build/bdist.darwin-8.7.1-i386/egg/Cheetah/CheetahWrapper.pys parseOptss6!  %"    cCsR|iotdti}ntdti}t|}tii |dS(Nsfile( sselfs isCompilesCompilerssyssstdinsoutputsTemplatesstrsstdoutswrite(sselfsoutput((s;build/bdist.darwin-8.7.1-i386/egg/Cheetah/CheetahWrapper.pyscompileOrFillStdins   cCs|i|i|if\}}} |i} |i }|i } |i }t i i|}|iodpd}|d|| |t i i|o |ii o|i}|d|nt}|d|ioPti| o || f}td|ntd| d|d |} ntd| d |i} t| }|ot!i"||n|ot i i| o)|iot#|qt i$|n|ii%ot&i%i'|n't(|d } | i'|| i*dS( Ns CompilingsFillings %s %s -> %s^s (backup %s)ssn%s: base name %s contains invalid characters. It must be named according to the same rules as Python modules.sfiles moduleNames mainClassNames searchListsw(+sselfschattersdebugswarnsCsDsWsbssrcsdstsbasesbasenamesosspathsdirnamesdstDirs isCompileswhatsexistssoptssnobackupsbaksNones moduleNameREsmatchstupsErrorsCompilersobjsTemplates searchListsstrsoutputsshutilscopyfilesmkdirsWithPyInitFilessmakedirssstdoutssysswritesopensfsclose(sselfsbsdstsdstDirsbasenameswhatsCsDstupsbasesWssrcsobjsfsoutputsbak((s;build/bdist.darwin-8.7.1-i386/egg/Cheetah/CheetahWrapper.pyscompileOrFillBundles@!    !         c Cs$|i|i|if\}}} t} h}xO|D]G}|i |i o||i i|iq4|ig||i Version: $Revision: 1.77 $ Start Date: 2001/09/19 Last Revision Date: $Date: 2005/11/27 03:37:22 $ """ __author__ = "Tavis Rudd " __revision__ = "$Revision: 1.77 $"[11:-2] import sys import os import os.path from os.path import getmtime, exists import re import types import time import random import warnings from Cheetah.Version import Version from Cheetah.SettingsManager import SettingsManager from Cheetah.Parser import Parser, ParseError, specialVarRE, STATIC_CACHE, REFRESH_CACHE from Cheetah.Utils.Indenter import indentize # an undocumented preprocessor from Cheetah import ErrorCatchers from Cheetah import NameMapper class Error(Exception): pass class GenUtils: """An abstract baseclass for the Compiler classes that provides methods that perform generic utility functions or generate pieces of output code from information passed in by the Parser baseclass. These methods don't do any parsing themselves.""" def genTimeInterval(self, timeString): ##@@ TR: need to add some error handling here if timeString[-1] == 's': interval = float(timeString[:-1]) elif timeString[-1] == 'm': interval = float(timeString[:-1])*60 elif timeString[-1] == 'h': interval = float(timeString[:-1])*60*60 elif timeString[-1] == 'd': interval = float(timeString[:-1])*60*60*24 elif timeString[-1] == 'w': interval = float(timeString[:-1])*60*60*24*7 else: # default to minutes interval = float(timeString)*60 return interval def genCacheInfo(self, cacheToken): """Decipher a placeholder cachetoken """ match = self._parser.cacheTokenRE.match(cacheToken) subGrpDict = match.groupdict() cacheInfo = {} if subGrpDict['REFRESH_CACHE']: cacheInfo['type'] = REFRESH_CACHE cacheInfo['interval'] = self.genTimeInterval(subGrpDict['interval']) elif subGrpDict['STATIC_CACHE']: cacheInfo['type'] = STATIC_CACHE return cacheInfo # is empty if no cache def genCacheInfoFromArgList(self, argList): cacheInfo = {'type':REFRESH_CACHE} for key, val in argList: if val[0] in '"\'': val = val[1:-1] if key == 'timer': key = 'interval' val = self.genTimeInterval(val) cacheInfo[key] = val return cacheInfo def genCheetahVar(self, nameChunks, plain=False): if nameChunks[0][0] in self.setting('gettextTokens'): self.addGetTextVar(nameChunks) if self.setting('useNameMapper') and not plain: return self.genNameMapperVar(nameChunks) else: return self.genPlainVar(nameChunks) def addGetTextVar(self, nameChunks): """Output something that gettext can recognize. This is a harmless side effect necessary to make gettext work when it is scanning compiled templates for strings marked for translation. """ # @@TR: this should be in the compiler not here self.addChunk("if False:") self.indent() self.addChunk(self.genPlainVar(nameChunks[:])) self.dedent() def genPlainVar(self, nameChunks): """Generate Python code for a Cheetah $var without using NameMapper (Unified Dotted Notation with the SearchList).""" nameChunks.reverse() chunk = nameChunks.pop() pythonCode = chunk[0] + chunk[2] while nameChunks: chunk = nameChunks.pop() pythonCode = (pythonCode + '.' + chunk[0] + chunk[2]) return pythonCode def genNameMapperVar(self, nameChunks): """Generate valid Python code for a Cheetah $var, using NameMapper (Unified Dotted Notation with the SearchList). nameChunks = list of var subcomponents represented as tuples [ (name,useAC,remainderOfExpr), ] where: name = the dotted name base useAC = where NameMapper should use autocalling on namemapperPart remainderOfExpr = any arglist, index, or slice If remainderOfExpr contains a call arglist (e.g. '(1234)') then useAC is False, otherwise it defaults to True. It is overridden by the global setting 'useAutocalling' if this setting is False. EXAMPLE ------------------------------------------------------------------------ if the raw Cheetah Var is $a.b.c[1].d().x.y.z nameChunks is the list [ ('a.b.c',True,'[1]'), # A ('d',False,'()'), # B ('x.y.z',True,''), # C ] When this method is fed the list above it returns VFN(VFN(VFFSL(SL, 'a.b.c',True)[1], 'd',False)(), 'x.y.z',True) which can be represented as VFN(B`, name=C[0], executeCallables=(useAC and C[1]))C[2] where: VFN = NameMapper.valueForName VFFSL = NameMapper.valueFromFrameOrSearchList VFSL = NameMapper.valueFromSearchList # optionally used instead of VFFSL SL = self.searchList() useAC = self.setting('useAutocalling') # True in this example A = ('a.b.c',True,'[1]') B = ('d',False,'()') C = ('x.y.z',True,'') C` = VFN( VFN( VFFSL(SL, 'a.b.c',True)[1], 'd',False)(), 'x.y.z',True) = VFN(B`, name='x.y.z', executeCallables=True) B` = VFN(A`, name=B[0], executeCallables=(useAC and B[1]))B[2] A` = VFFSL(SL, name=A[0], executeCallables=(useAC and A[1]))A[2] Note, if the compiler setting useStackFrames=False (default is true) then A` = VFSL([locals()]+SL+[globals(), __builtin__], name=A[0], executeCallables=(useAC and A[1]))A[2] This option allows Cheetah to be used with Psyco, which doesn't support stack frame introspection. """ defaultUseAC = self.setting('useAutocalling') useSearchList = self.setting('useSearchList') nameChunks.reverse() name, useAC, remainder = nameChunks.pop() if not useSearchList: firstDotIdx = name.find('.') if firstDotIdx != -1 and firstDotIdx < len(name): beforeFirstDot, afterDot = name[:firstDotIdx], name[firstDotIdx+1:] pythonCode = ('VFN(' + beforeFirstDot + ',"' + afterDot + '",' + repr(defaultUseAC and useAC) + ')' + remainder) #print 'DEBUG1: ', pythonCode, name, remainder else: pythonCode = name+remainder #print 'DEBUG2: ', pythonCode, name, remainder elif self.setting('useStackFrames'): pythonCode = ('VFFSL(SL,' '"'+ name + '",' + repr(defaultUseAC and useAC) + ')' + remainder) else: pythonCode = ('VFSL([locals()]+SL+[globals(), __builtin__],' '"'+ name + '",' + repr(defaultUseAC and useAC) + ')' + remainder) while nameChunks: name, useAC, remainder = nameChunks.pop() pythonCode = ('VFN(' + pythonCode + ',"' + name + '",' + repr(defaultUseAC and useAC) + ')' + remainder) return pythonCode ################################################## ## METHOD COMPILERS class MethodCompiler(GenUtils): def __init__(self, methodName, classCompiler, templateObj=None): self._settingsManager = classCompiler self._templateObj = templateObj self._methodName = methodName self._setupState() def setting(self, key): return self._settingsManager.setting(key) def _setupState(self): self._indent = self.setting('indentationStep') self._indentLev = self.setting('initialMethIndentLevel') self._pendingStrConstChunks = [] self._methodSignature = None self._methodDef = None self._docStringLines = [] self._methodBodyChunks = [] self._cacheRegionOpen = False def cleanupState(self): """Called by the containing class compiler instance""" pass def methodName(self): return self._methodName def setMethodName(self, name): self._methodName = name ## methods for managing indentation def indentation(self): return self._indent * self._indentLev def indent(self): self._indentLev +=1 def dedent(self): if self._indentLev: self._indentLev -=1 else: raise Error('Attempt to dedent when the indentLev is 0') ## methods for final code wrapping def methodDef(self): if self._methodDef: return self._methodDef else: return self.wrapCode() __str__ = methodDef def wrapCode(self): self.commitStrConst() methodDefChunks = ( self.methodSignature(), '\n', self.docString(), self.methodBody(), ) methodDef = ''.join(methodDefChunks) self._methodDef = methodDef return methodDef def methodSignature(self): return self._indent + self._methodSignature + ':' def setMethodSignature(self, signature): self._methodSignature = signature def methodBody(self): return ''.join( self._methodBodyChunks ) def docString(self): ind = self._indent*2 docStr = (ind + '"""\n' + ind + ('\n' + ind).join(self._docStringLines) + '\n' + ind + '"""\n') return docStr ## methods for adding code def addMethDocString(self, line): self._docStringLines.append(line.replace('%','%%')) def addChunk(self, chunk): self.commitStrConst() chunk = "\n" + self.indentation() + chunk self._methodBodyChunks.append(chunk) def appendToPrevChunk(self, appendage): self._methodBodyChunks[-1] = self._methodBodyChunks[-1] + appendage def addWriteChunk(self, chunk): self.addChunk('write(' + chunk + ')') def addFilteredChunk(self, chunk, filterArgs=None, rawExpr=None): """ """ if filterArgs is None: filterArgs = '' if self.setting('includeRawExprInFilterArgs') and rawExpr: filterArgs += ', rawExpr=%s'%repr(rawExpr) if self.setting('alwaysFilterNone'): self.addChunk("__v = %s"%chunk) if self.setting('useFilters'): self.addChunk("if __v is not None: write(filter(__v%s))"%filterArgs) else: self.addChunk("if __v is not None: write(str(__v))") else: if self.setting('useFilters'): self.addChunk("write(filter(%s%s))"%(chunk,filterArgs)) else: self.addChunk("write(str(%s))"%chunk) # @@TR: consider merging the next two methods into one def addStrConst(self, strConst): self._appendToPrevStrConst(strConst) def addRawText(self, text): self.addStrConst(text) def _appendToPrevStrConst(self, strConst): if self._pendingStrConstChunks: self._pendingStrConstChunks.append(strConst) else: self._pendingStrConstChunks = [strConst] def _unescapeCheetahVars(self, theString): """Unescape any escaped Cheetah \$vars in the string.""" token = self.setting('cheetahVarStartToken') return theString.replace('\\' + token, token) def _unescapeDirectives(self, theString): """Unescape any escaped Cheetah \$vars in the string.""" token = self.setting('directiveStartToken') return theString.replace('\\' + token, token) def commitStrConst(self): """Add the code for outputting the pending strConst without chopping off any whitespace from it. """ if self._pendingStrConstChunks: strConst = self._unescapeCheetahVars(''.join(self._pendingStrConstChunks)) strConst = self._unescapeDirectives(strConst) self._pendingStrConstChunks = [] if self.setting('reprShortStrConstants') and \ strConst.count('\n') < self.setting('reprNewlineThreshold'): self.addWriteChunk( repr(strConst).replace('\\012','\\n')) else: strConst = strConst.replace('\\','\\\\').replace("'''","'\'\'\'") if strConst[0] == "'": strConst = '\\' + strConst if strConst[-1] == "'": strConst = strConst[:-1] + '\\' + strConst[-1] self.addWriteChunk("'''" + strConst + "'''" ) def handleWSBeforeDirective(self): """Truncate the pending strCont to the beginning of the current line. """ if self._pendingStrConstChunks: src = self._pendingStrConstChunks[-1] BOL = max(src.rfind('\n')+1, src.rfind('\r')+1, 0) if BOL < len(src): self._pendingStrConstChunks[-1] = src[:BOL] def addMethComment(self, comm): offSet = self.setting('commentOffset') self.addChunk('#' + ' '*offSet + comm) def addSilent(self, expr): self.addChunk( expr ) def addSet(self, LVALUE, OP, RVALUE, isGlobal=True): ## we need to split the LVALUE to deal with globalSetVars splitPos1 = LVALUE.find('.') splitPos2 = LVALUE.find('[') if splitPos1 > 0 and splitPos2==-1: splitPos = splitPos1 elif splitPos1 > 0 and splitPos1 < max(splitPos2,0): splitPos = splitPos1 else: splitPos = splitPos2 if splitPos >0: primary = LVALUE[:splitPos] secondary = LVALUE[splitPos:] else: primary = LVALUE secondary = '' if isGlobal: LVALUE = 'globalSetVars["' + primary + '"]' + secondary else: pass self.addChunk( LVALUE + ' ' + OP + ' ' + RVALUE.strip() ) def addInclude(self, sourceExpr, includeFrom, isRaw): # @@TR: consider soft-coding this self.addChunk('self._includeCheetahSource(' + sourceExpr + ', trans=trans, ' + 'includeFrom="' + includeFrom + '", raw=' + repr(isRaw) + ')') def addWhile(self, expr): self.addIndentingDirective(expr) def addFor(self, expr): self.addIndentingDirective(expr) def addRepeat(self, expr): #the _repeatCount stuff here allows nesting of #repeat directives self._repeatCount = getattr(self, "_repeatCount", -1) + 1 self.addFor('for __i%s in range(%s)' % (self._repeatCount,expr)) def addIndentingDirective(self, expr): if expr and not expr[-1] == ':': expr = expr + ':' self.addChunk( expr ) self.indent() def addReIndentingDirective(self, expr): self.commitStrConst() self.dedent() if not expr[-1] == ':': expr = expr + ':' self.addChunk( expr ) self.indent() def addIf(self, expr): """For a full #if ... #end if directive """ self.addIndentingDirective(expr) def addOneLineIf(self, conditionExpr, trueExpr, falseExpr): """For a single-lie #if ... then .... else ... directive then else """ self.addIndentingDirective(conditionExpr) self.addFilteredChunk(trueExpr) self.dedent() self.addIndentingDirective('else') self.addFilteredChunk(falseExpr) self.dedent() def addElse(self, expr): expr = re.sub(r'else[ \f\t]+if','elif', expr) self.addReIndentingDirective(expr) def addUnless(self, expr): self.addIf('if not (' + expr + ')') def addTry(self, expr): self.addIndentingDirective(expr) def addExcept(self, expr): self.addReIndentingDirective(expr) def addFinally(self, expr): self.addReIndentingDirective(expr) def addReturn(self, expr): self.addChunk(expr) def addPSP(self, PSP): self.commitStrConst() autoIndent = False if PSP[0] == '=': PSP = PSP[1:] if PSP: self.addWriteChunk('filter(' + PSP + ')') return elif PSP.lower() == 'end': self.dedent() return elif PSP[-1] == '$': autoIndent = True PSP = PSP[:-1] elif PSP[-1] == ':': autoIndent = True for line in PSP.splitlines(): self.addChunk(line) if autoIndent: self.indent() def nextCacheID(self): return str(random.randrange(100, 999)) \ + str(random.randrange(10000, 99999)) def startCacheRegion(self, cacheInfo, lineCol): ID = self.nextCacheID() interval = cacheInfo.get('interval',None) test = cacheInfo.get('test',None) customID = cacheInfo.get('id',None) if customID: ID = repr(customID) varyBy = cacheInfo.get('varyBy',ID) self._cacheRegionOpen = True # attrib of current methodCompiler self.addChunk('## START CACHE REGION: at line, col ' + str(lineCol) + ' in the source.') self.addChunk('RECACHE = False') self.addChunk('region = self._cacheRegions.get(' + ID + ')') self.addChunk('if not region:') self.indent() self.addChunk("region = CacheRegion()") self.addChunk("self._cacheRegions[" + ID + "] = region") self.addChunk('RECACHE = True') self.dedent() self.addChunk('cache = region.getCache('+varyBy+')') if interval: self.addMethDocString('This cache will be refreshed every ' + str(interval) + ' seconds.') self.addChunk('if (not cache.getRefreshTime())' + ' or (currentTime() > cache.getRefreshTime()):') self.indent() self.addChunk("cache.setRefreshTime(currentTime() +" + str(interval) + ")") self.addChunk('RECACHE = True') self.dedent() if test: self.addChunk('if ' + test + ':') self.indent() self.addChunk('RECACHE = True') self.dedent() self.addChunk('if RECACHE or not cache.getData():') self.indent() self.addChunk('orig_trans = trans') self.addChunk('trans = cacheCollector = DummyTransaction()') self.addChunk('write = cacheCollector.response().write') def endCacheRegion(self): self._cacheRegionOpen = False self.addChunk('trans = orig_trans') self.addChunk('write = trans.response().write') self.addChunk('cache.setData(cacheCollector.response().getvalue())') self.addChunk('del cacheCollector') self.dedent() self.addWriteChunk('cache.getData()') self.addChunk('## END CACHE REGION') self.addChunk('') def setErrorCatcher(self, errorCatcherName): if self._templateObj: self._templateObj._errorCatcher = \ getattr(ErrorCatchers, errorCatcherName)(self._templateObj) self.addChunk('if self._errorCatchers.has_key("' + errorCatcherName + '"):') self.indent() self.addChunk('self._errorCatcher = self._errorCatchers["' + errorCatcherName + '"]') self.dedent() self.addChunk('else:') self.indent() self.addChunk('self._errorCatcher = self._errorCatchers["' + errorCatcherName + '"] = ErrorCatchers.' + errorCatcherName + '(self)' ) self.dedent() def setFilter(self, theFilter, isKlass): if isKlass: self.addChunk('filter = self._currentFilter = ' + theFilter.strip() + '(self).filter') else: if theFilter.lower() == 'none': self.addChunk('filter = self._initialFilter') else: # is string representing the name of a builtin filter self.addChunk('filterName = ' + repr(theFilter)) self.addChunk('if self._filters.has_key("' + theFilter + '"):') self.indent() self.addChunk('filter = self._currentFilter = self._filters[filterName]') self.dedent() self.addChunk('else:') self.indent() self.addChunk('filter = self._currentFilter = \\\n\t\t\tself._filters[filterName] = ' + 'getattr(self._filtersLib, filterName)(self).filter') self.dedent() class AutoMethodCompiler(MethodCompiler): def _setupState(self): MethodCompiler._setupState(self) self._argStringList = [ ("self",None) ] self._streamingEnabled = True def cleanupState(self): MethodCompiler.cleanupState(self) self.commitStrConst() if self._cacheRegionOpen: self.endCacheRegion() self._indentLev = self.setting('initialMethIndentLevel') mainBodyChunks = self._methodBodyChunks self._methodBodyChunks = [] self._addAutoSetupCode() self._methodBodyChunks.extend(mainBodyChunks) self._addAutoCleanupCode() if self._streamingEnabled: argList = [ ('trans', 'None'), #("dummyTrans","False"), ] if self.setting('useNameMapper'): argList.extend([("VFFSL","valueFromFrameOrSearchList"), ("VFN","valueForName")]) for argName, defVal in argList: self.addMethArg(argName, defVal) def _addAutoSetupCode(self): if self._streamingEnabled: self.addChunk('if not trans: trans = self.transaction' ' # is None unless self.awake() was called') self.addChunk('if not trans:') self.indent() self.addChunk('trans = DummyTransaction()') if self.setting('autoAssignDummyTransactionToSelf'): self.addChunk('self.transaction = trans') self.addChunk('dummyTrans = True') self.dedent() self.addChunk('else: dummyTrans = False') else: self.addChunk('trans = DummyTransaction()') self.addChunk('dummyTrans = True') self.addChunk('write = trans.response().write') if self.setting('useNameMapper'): self.addChunk('SL = self._searchList') self.addChunk('globalSetVars = self._globalSetVars') if self.setting('useFilters'): self.addChunk('filter = self._currentFilter') self.addChunk('') self.addChunk("#" *40) self.addChunk('## START - generated method body') self.addChunk('') def _addAutoCleanupCode(self): self.addChunk('') self.addChunk("#" *40) self.addChunk('## END - generated method body') self.addChunk('') self.addStop() self.addChunk('') def addStop(self, expr=None): self.addChunk('return dummyTrans and trans.response().getvalue() or ""') def addMethArg(self, name, defVal=None): asteriskPos = max(name.rfind('*')+1, 0) if asteriskPos: self._streamingEnabled = False self._argStringList.append( (name,defVal) ) def methodSignature(self): argStringChunks = [] for arg in self._argStringList: chunk = arg[0] if not arg[1] == None: chunk += '=' + arg[1] argStringChunks.append(chunk) return (self._indent + "def " + self.methodName() + "(" + (',\n' + self._indent*3).join(argStringChunks) + "):\n\n") ################################################## ## CLASS COMPILERS class ClassCompiler(GenUtils): methodCompilerClass = AutoMethodCompiler methodCompilerClassForInit = MethodCompiler def __init__(self, className, mainMethodName='respond', templateObj=None, fileName=None, settingsManager=None): self._settingsManager = settingsManager self._fileName = fileName self._className = className self._mainMethodName = mainMethodName self._templateObj = templateObj self._setupState() methodCompiler = self._spawnMethodCompiler(mainMethodName) methodCompiler.addMethDocString('This is the main method generated by Cheetah') self._setActiveMethodCompiler(methodCompiler) if fileName and self.setting('monitorSrcFile'): self._addSourceFileMonitoring(fileName) def setting(self, key): return self._settingsManager.setting(key) def __getattr__(self, name): """Provide access to the methods and attributes of the MethodCompiler at the top of the activeMethods stack: one-way namespace sharing WARNING: Use .setMethods to assign the attributes of the MethodCompiler from the methods of this class!!! or you will be assigning to attributes of this object instead.""" if self.__dict__.has_key(name): return self.__dict__[name] elif hasattr(self.__class__, name): return getattr(self.__class__, name) elif self._activeMethodsList and hasattr(self._activeMethodsList[-1], name): return getattr(self._activeMethodsList[-1], name) else: raise AttributeError, name def _setupState(self): self._classDef = None self._activeMethodsList = [] # stack while parsing/generating self._finishedMethodsList = [] # store by order self._methodsIndex = {} # store by name self._baseClass = 'Template' self._classDocStringLines = [] self._generatedAttribs = [] # printed after methods in the gen class def self._initMethChunks = [] self._alias__str__ = True # should we set the __str__ alias self._blockMetaData = {} self._errorCatcherCount = 0 self._placeholderToErrorCatcherMap = {} def cleanupState(self): while self._activeMethodsList: methCompiler = self._popActiveMethodCompiler() self._swallowMethodCompiler(methCompiler) self._setupInitMethod() if self._mainMethodName == 'respond': self._generatedAttribs.append('__str__ = respond') if self._templateObj: self._templateObj.__str__ = self._templateObj.respond self.addAttribute('_mainCheetahMethod_for_' + self._className + '= ' + repr(self._mainMethodName) ) def _setupInitMethod(self): __init__ = self._spawnMethodCompiler('__init__', klass=self.methodCompilerClassForInit) __init__.setMethodSignature("def __init__(self, *args, **KWs)") __init__.addChunk("%s.__init__(self, *args, **KWs)" % self._baseClass) for chunk in self._initMethChunks: __init__.addChunk(chunk) __init__.cleanupState() self._swallowMethodCompiler(__init__, pos=0) def _addSourceFileMonitoring(self, fileName): # the first bit is added to init self.addChunkToInit('self._filePath = ' + repr(fileName)) self.addChunkToInit('self._fileMtime = ' + str(getmtime(fileName)) ) if self._templateObj: setattr(self._templateObj, '_filePath', fileName) setattr(self._templateObj, '_fileMtime', getmtime(fileName)) # the rest is added to the main output method of the class ('mainMethod') self.addChunk('if exists(self._filePath) and ' + 'getmtime(self._filePath) > self._fileMtime:') self.indent() self.addChunk('self.compile(file=self._filePath, moduleName=' +className + ')') self.addChunk( 'write(getattr(self, self._mainCheetahMethod_for_' + self._className + ')(trans=trans))') self.addStop() self.dedent() def setClassName(self, name): self._className = name def className(self): return self._className def setBaseClass(self, baseClassName): self._baseClass = baseClassName def setMainMethodName(self, methodName): ## change the name in the methodCompiler and add new reference mainMethod = self._methodsIndex[self._mainMethodName] mainMethod.setMethodName(methodName) self._methodsIndex[methodName] = mainMethod ## make sure that fileUpdate code still works properly: chunkToChange = ('write(self.' + self._mainMethodName + '(trans=trans))') chunks = mainMethod._methodBodyChunks if chunkToChange in chunks: for i in range(len(chunks)): if chunks[i] == chunkToChange: chunks[i] = ('write(self.' + methodName + '(trans=trans))') ## get rid of the old reference and update self._mainMethodName del self._methodsIndex[self._mainMethodName] self._mainMethodName = methodName def _spawnMethodCompiler(self, methodName, klass=None): if klass is None: klass = self.methodCompilerClass methodCompiler = klass(methodName, classCompiler=self, templateObj=self._templateObj) self._methodsIndex[methodName] = methodCompiler return methodCompiler def _setActiveMethodCompiler(self, methodCompiler): self._activeMethodsList.append(methodCompiler) def _getActiveMethodCompiler(self): return self._activeMethodsList[-1] def _popActiveMethodCompiler(self): return self._activeMethodsList.pop() def _swallowMethodCompiler(self, methodCompiler, pos=None): methodCompiler.cleanupState() if pos==None: self._finishedMethodsList.append( methodCompiler ) else: self._finishedMethodsList.insert(pos, methodCompiler) if self._templateObj and methodCompiler.methodName() != '__init__': self._templateObj._bindCompiledMethod(methodCompiler) return methodCompiler def startMethodDef(self, methodName, argsList, parserComment): methodCompiler = self._spawnMethodCompiler(methodName) self._setActiveMethodCompiler(methodCompiler) ## deal with the method's argstring for argName, defVal in argsList: methodCompiler.addMethArg(argName, defVal) methodCompiler.addMethDocString(parserComment) def _finishedMethods(self): return self._finishedMethodsList def addClassDocString(self, line): self._classDocStringLines.append( line.replace('%','%%')) def addChunkToInit(self,chunk): self._initMethChunks.append(chunk) def addAttribute(self, attribExpr): ## first test to make sure that the user hasn't used any fancy Cheetah syntax # (placeholders, directives, etc.) inside the expression if attribExpr.find('VFN(') != -1 or attribExpr.find('VFFSL(') != -1: raise ParseError(self, 'Invalid #attr directive.' + ' It should only contain simple Python literals.') ## now add the attribute self._generatedAttribs.append(attribExpr) if self._templateObj: exec('self._templateObj.' + attribExpr.strip()) def addSettingsToInit(self, settingsStr, settingsType='ini'): #@@TR 2005-01-01: this may not be used anymore? if settingsType=='python': reader = 'updateSettingsFromPySrcStr' else: reader = 'updateSettingsFromConfigStr' settingsCode = ("self." + reader + "('''" + settingsStr.replace("'''","\'\'\'") + "''')") self.addChunkToInit(settingsCode) def addErrorCatcherCall(self, codeChunk, rawCode='', lineCol=''): if self._placeholderToErrorCatcherMap.has_key(rawCode): methodName = self._placeholderToErrorCatcherMap[rawCode] if not self.setting('outputRowColComments'): self._methodsIndex[methodName].addMethDocString( 'plus at line, col ' + str(lineCol)) return methodName self._errorCatcherCount += 1 methodName = '__errorCatcher' + str(self._errorCatcherCount) self._placeholderToErrorCatcherMap[rawCode] = methodName catcherMeth = self._spawnMethodCompiler(methodName, klass=MethodCompiler) catcherMeth.setMethodSignature('def ' + methodName + '(self, localsDict={})') # is this use of localsDict right? catcherMeth.addMethDocString('Generated from ' + rawCode + ' at line, col ' + str(lineCol) + '.') catcherMeth.addChunk('try:') catcherMeth.indent() catcherMeth.addChunk("return eval('''" + codeChunk + "''', globals(), localsDict)") catcherMeth.dedent() catcherMeth.addChunk('except self._errorCatcher.exceptions(), e:') catcherMeth.indent() catcherMeth.addChunk("return self._errorCatcher.warn(exc_val=e, code= " + repr(codeChunk) + " , rawCode= " + repr(rawCode) + " , lineCol=" + str(lineCol) +")") catcherMeth.cleanupState() self._swallowMethodCompiler(catcherMeth) return methodName def closeDef(self): self.commitStrConst() methCompiler = self._popActiveMethodCompiler() self._swallowMethodCompiler(methCompiler) def closeBlock(self): self.commitStrConst() methCompiler = self._popActiveMethodCompiler() methodName = methCompiler.methodName() if self.setting('includeBlockMarkers'): endMarker = self.setting('blockMarkerEnd') methCompiler.addStrConst(endMarker[0] + methodName + endMarker[1]) self._swallowMethodCompiler(methCompiler) #metaData = self._blockMetaData[methodName] #rawDirective = metaData['raw'] #lineCol = metaData['lineCol'] ## insert the code to call the block, caching if #cache directive is on codeChunk = 'self.' + methodName + '(trans=trans)' self.addChunk(codeChunk) #self.appendToPrevChunk(' # generated from ' + repr(rawDirective) ) #if self.setting('outputRowColComments'): # self.appendToPrevChunk(' at line %s, col %s' % lineCol + '.') ## code wrapping methods def classDef(self): if self._classDef: return self._classDef else: return self.wrapClassDef() __str__ = classDef def wrapClassDef(self): self.addClassDocString('') self.addClassDocString(self.setting('defDocStrMsg')) ind = self.setting('indentationStep') classDefChunks = ( self.classSignature(), self.classDocstring(), ind + '#'*50, ind + '## GENERATED METHODS', '\n', self.methodDefs(), ind + '#'*50, ind + '## GENERATED ATTRIBUTES', '\n', self.attributes(), ) classDef = '\n'.join(classDefChunks) self._classDef = classDef return classDef def classSignature(self): return "class %s(%s):" % (self.className(), self._baseClass) def classDocstring(self): ind = self.setting('indentationStep') docStr = ('%(ind)s"""\n%(ind)s' + '\n%(ind)s'.join(self._classDocStringLines) + '\n%(ind)s"""\n' ) % {'ind':ind} return docStr def methodDefs(self): methodDefs = [str(methGen) for methGen in self._finishedMethods() ] return '\n\n'.join(methodDefs) def attributes(self): attribs = [self.setting('indentationStep') + str(attrib) for attrib in self._generatedAttribs ] return '\n\n'.join(attribs) class AutoClassCompiler(ClassCompiler): pass ################################################## ## MODULE COMPILERS #class ModuleCompiler(Parser, GenUtils): class ModuleCompiler(SettingsManager, GenUtils): parserClass = Parser classCompilerClass = AutoClassCompiler def __init__(self, source=None, file=None, moduleName='GenTemplate', mainClassName=None, mainMethodName='respond', templateObj=None, settings=None): SettingsManager.__init__(self) if settings: self.updateSettings(settings) # disable useStackFrames if the C version of NameMapper isn't compiled # it's painfully slow in the Python version and bites Windows users all # the time: if not NameMapper.C_VERSION: warnings.warn( "\nYou don't have the C version of NameMapper installed! " "I'm disabling Cheetah's useStackFrames option as it is " "painfully slow with the Python version of NameMapper. " "You should get a copy of Cheetah with the compiled C version of NameMapper." ) self.setSetting('useStackFrames', False) self._templateObj = templateObj self._compiled = False self._moduleName = moduleName if not mainClassName: self._mainClassName = moduleName else: self._mainClassName = mainClassName self._mainMethodName = mainMethodName self._filePath = None self._fileMtime = None if source and file: raise TypeError("Cannot compile from a source string AND file.") elif isinstance(file, types.StringType) or isinstance(file, types.UnicodeType): # it's a filename. f = open(file) # Raises IOError. source = f.read() f.close() self._filePath = file self._fileMtime = os.path.getmtime(file) elif hasattr(file, 'read'): source = file.read() # Can't set filename or mtime--they're not accessible. elif file: raise TypeError("'file' argument must be a filename string or file-like object") if self._filePath: self._fileDirName, self._fileBaseName = os.path.split(self._filePath) self._fileBaseNameRoot, self._fileBaseNameExt = \ os.path.splitext(self._fileBaseName) if not (isinstance(source, str) or isinstance(source, unicode)): source = str( source ) # by converting to string here we allow objects such as other Templates # to be passed in # Handle the #indent directive by converting it to other directives. # (Over the long term we'll make it a real directive.) if source == "": warnings.warn("You supplied an empty string for the source!", ) if source.find('#indent') != -1: #@@TR: undocumented hack source = indentize(source) self._parser = self.parserClass(source, filename=self._filePath, compiler=self) self._setupCompilerState() def __getattr__(self, name): """Provide one-way access to the methods and attributes of the ClassCompiler, and thereby the MethodCompilers as well. WARNING: Use .setMethods to assign the attributes of the ClassCompiler from the methods of this class!!! or you will be assigning to attributes of this object instead.""" if self.__dict__.has_key(name): return self.__dict__[name] elif hasattr(self.__class__, name): return getattr(self.__class__, name) elif self._activeClassesList and hasattr(self._activeClassesList[-1], name): return getattr(self._activeClassesList[-1], name) else: raise AttributeError, name def _initializeSettings(self): defaults = { 'indentationStep': ' '*4, 'initialMethIndentLevel': 2, 'monitorSrcFile':False, ## controlling the handling of Cheetah $vars 'useNameMapper': True, # Unified dotted notation and the searchList 'useSearchList': True, # if false, assume the first # portion of the $variable (before the first dot) is a global, # builtin, or local var that doesn't need # looking up in the searchlist BUT use # namemapper on the rest of the lookup 'useAutocalling': True, # detect and call callable()'s, requires NameMapper 'useStackFrames': True, # use NameMapper.valueFromFrameOrSearchList # rather than NameMapper.valueFromSearchList 'useErrorCatcher':False, # the next four are new in 1.0rc2 'alwaysFilterNone':True, # filter out None, before the filter is called 'useFilters':True, # use str instead if =False 'includeRawExprInFilterArgs':True, 'autoAssignDummyTransactionToSelf':False, ## controlling the aesthetic appearance of the generated code 'commentOffset': 1, # should shorter str constant chunks be printed using repr rather than ''' quotes 'reprShortStrConstants': True, 'reprNewlineThreshold':3, 'outputRowColComments':True, ## should #block's be wrapped in a comment in the template's output 'includeBlockMarkers': False, 'blockMarkerStart':('\n\n'), 'blockMarkerEnd':('\n\n'), 'defDocStrMsg':'Autogenerated by CHEETAH: The Python-Powered Template Engine', 'gettextTokens': ["_", "N_", "ngettext"], ## @@TR: The following really belong in the parser, but I've put them ## here for the time being to facilitate separating the parser and ## compiler: 'cheetahVarStartToken':'$', 'commentStartToken':'##', 'multiLineCommentStartToken':'#*', 'multiLineCommentEndToken':'*#', 'directiveStartToken':'#', 'directiveEndToken':'#', 'PSPStartToken':'<%', 'PSPEndToken':'%>', } self.updateSettings( defaults ) def _setupCompilerState(self): self._activeClassesList = [] self._finishedClassesList = [] # listed by ordered self._finishedClassIndex = {} # listed by name self._moduleDef = None self._moduleShBang = '#!/usr/bin/env python' self._moduleEncoding = '' self._moduleHeaderLines = [] self._moduleDocStringLines = [] self._specialVars = {} self._importStatements = [ "import sys", "import os", "import os.path", "from os.path import getmtime, exists", "import time", "import types", "import __builtin__", "from Cheetah.Template import Template", "from Cheetah.DummyTransaction import DummyTransaction", "from Cheetah.NameMapper import NotFound, valueForName, valueFromSearchList, valueFromFrameOrSearchList", "from Cheetah.CacheRegion import CacheRegion", "import Cheetah.Filters as Filters", "import Cheetah.ErrorCatchers as ErrorCatchers", ] self._importedVarNames = ['sys', 'os', 'os.path', 'time', 'types', 'Template', 'DummyTransaction', 'NotFound', 'Filters', 'ErrorCatchers', 'CacheRegion', ] self._moduleConstants = [ "try:", " True, False", "except NameError:", " True, False = (1==1), (1==0)", "VFFSL=valueFromFrameOrSearchList", "VFSL=valueFromSearchList", "VFN=valueForName", "currentTime=time.time", ] self._errorCatcherOn = False def compile(self): classCompiler = self._spawnClassCompiler(self._mainClassName) self._addActiveClassCompiler(classCompiler) self._parser.parse() self._swallowClassCompiler(self._popActiveClassCompiler()) self._compiled = True def _spawnClassCompiler(self, className, klass=None, mainMethodName='respond'): if klass is None: klass = self.classCompilerClass classCompiler = klass(className, mainMethodName=self._mainMethodName, templateObj=self._templateObj, fileName=self._filePath, settingsManager=self, ) return classCompiler def _addActiveClassCompiler(self, classCompiler): self._activeClassesList.append(classCompiler) def _getActiveClassCompiler(self): return self._activeClassesList[-1] def _popActiveClassCompiler(self): return self._activeClassesList.pop() def _swallowClassCompiler(self, classCompiler): classCompiler.cleanupState() self._finishedClassesList.append( classCompiler ) self._finishedClassIndex[classCompiler.className()] = classCompiler return classCompiler def _finishedClasses(self): return self._finishedClassesList def importedVarNames(self): return self._importedVarNames def addImportedVarNames(self, varNames): self._importedVarNames.extend(varNames) def isErrorCatcherOn(self): return self._errorCatcherOn def turnErrorCatcherOn(self): self._errorCatcherOn = True def turnErrorCatcherOff(self): self._errorCatcherOn = False ## methods for adding stuff to the module and class definitions def setBaseClass(self, baseClassName): # change the default mainMethodName from the default 'respond' self.setMainMethodName('writeBody') # @@TR: needs some thought ################################################## ## If the #extends directive contains a classname or modulename that isn't # in self.importedVarNames() already, we assume that we need to add # an implied 'from ModName import ClassName' where ModName == ClassName. # - This is the case in WebKit servlet modules. # - We also assume that the final . separates the classname from the # module name. This might break if people do something really fancy # with their dots and namespaces. chunks = baseClassName.split('.') if len(chunks) > 1: modName, bareClassName = '.'.join(chunks[:-1]), chunks[-1] else: # baseClassName is either unimported modName # or a previously imported classname modName = bareClassName = baseClassName if modName not in self.importedVarNames(): if len(chunks) > 1 and bareClassName != chunks[:-1][-1]: modName = '.'.join(chunks) importStatement = "from %s import %s" % (modName, bareClassName) self.addImportStatement(importStatement) self.addImportedVarNames( [bareClassName,] ) self._getActiveClassCompiler().setBaseClass(bareClassName) ################################################## ## dynamically bind to and __init__ with this new baseclass # - this is required for dynamic use of templates compiled directly from file # - also necessary for the 'monitorSrc' fileMtime triggered recompiles if self._templateObj: mod = self._templateObj._importAsDummyModule('\n'.join(self._importStatements)) class newClass: pass newClass.__name__ = self._mainClassName __bases__ = (getattr(mod, self._baseClass), ) newClass.__bases__ = __bases__ self._templateObj.__class__ = newClass # must initialize it so instance attributes are accessible newClass.__init__(self._templateObj, _globalSetVars=self._templateObj._globalSetVars, _preBuiltSearchList=self._templateObj._searchList) def setCompilerSetting(self, key, valueExpr): self.setSetting(key, eval(valueExpr) ) self._parser.configureParser() def setCompilerSettings(self, keywords, settingsStr): KWs = keywords merge = True if 'nomerge' in KWs: merge = False if 'reset' in KWs: # @@TR: this is actually caught by the parser at the moment. # subject to change in the future self._initializeSettings() self._parser.configureParser() return elif 'python' in KWs: settingsReader = self.updateSettingsFromPySrcStr # this comes from SettingsManager else: # this comes from SettingsManager settingsReader = self.updateSettingsFromConfigStr settingsReader(settingsStr) self._parser.configureParser() def setShBang(self, shBang): self._moduleShBang = shBang def setModuleEncoding(self, encoding): self._moduleEncoding = '# -*- coding: %s -*-' %encoding def addModuleHeader(self, line): self._moduleHeaderLines.append(line) def addModuleDocString(self, line): self._moduleDocStringLines.append(line) def addSpecialVar(self, basename, contents): self._specialVars['__' + basename + '__'] = contents.strip() def addImportStatement(self, impStatement): self._importStatements.append(impStatement) #@@TR 2005-01-01: there's almost certainly a cleaner way to do this! importVarNames = impStatement[impStatement.find('import') + len('import'):].split(',') importVarNames = [var.split()[-1] for var in importVarNames] # handles aliases importVarNames = [var for var in importVarNames if var!='*'] self.addImportedVarNames(importVarNames) #used by #extend for auto-imports if self._templateObj: import Template as TemplateMod mod = self._templateObj._importAsDummyModule(impStatement) # @@TR 2005-01-15: testing this approach to support # 'from foo import *' self._templateObj._searchList.append(mod) # @@TR: old buggy approach is still needed for now for varName in importVarNames: if varName == '*': continue val = getattr(mod, varName.split('.')[0]) setattr(TemplateMod, varName, val) def addGlobalCodeChunk(self, codeChunk): self._globalCodeChunks.append(codeChunk) def addAttribute(self, attribName, expr): self._getActiveClassCompiler().addAttribute(attribName + ' =' + expr) if self._templateObj: # @@TR: this code should be delegated to the compiler val = eval(expr,{},{}) setattr(self._templateObj, attribName, val) def addComment(self, comm): if re.match(r'#+$',comm): # skip bar comments return specialVarMatch = specialVarRE.match(comm) if specialVarMatch: return self.addSpecialVar(specialVarMatch.group(1), comm[specialVarMatch.end():]) elif comm.startswith('doc:'): addLine = self.addMethDocString comm = comm[len('doc:'):].strip() elif comm.startswith('doc-method:'): addLine = self.addMethDocString comm = comm[len('doc-method:'):].strip() elif comm.startswith('doc-module:'): addLine = self.addModuleDocString comm = comm[len('doc-module:'):].strip() elif comm.startswith('doc-class:'): addLine = self.addClassDocString comm = comm[len('doc-class:'):].strip() elif comm.startswith('header:'): addLine = self.addModuleHeader comm = comm[len('header:'):].strip() else: addLine = self.addMethComment for line in comm.splitlines(): addLine(line) ## methods for module code wrapping def moduleDef(self): if not self._compiled: self.compile() if self._moduleDef: return self._moduleDef else: return self.wrapModuleDef() __str__ = moduleDef def wrapModuleDef(self): self.addModuleDocString('') self.addModuleDocString(self.setting('defDocStrMsg')) self.addModuleDocString(' CHEETAH VERSION: ' + Version) self.addSpecialVar('CHEETAH_version', Version) self.addModuleDocString(' Generation time: ' + self.timestamp()) self.addSpecialVar('CHEETAH_genTime', self.timestamp()) if self._filePath: self.addSpecialVar('CHEETAH_src', self._filePath) self.addModuleDocString(' Source file: ' + self._filePath) self.addModuleDocString(' Source file last modified: ' + self.timestamp(self._fileMtime)) moduleDef = """%(header)s %(docstring)s %(specialVars)s ################################################## ## DEPENDENCIES %(imports)s ################################################## ## MODULE CONSTANTS %(constants)s ################################################## ## CLASSES %(classes)s %(footer)s """ % {'header':self.moduleHeader(), 'docstring':self.moduleDocstring(), 'specialVars':self.specialVars(), 'imports':self.importStatements(), 'constants':self.moduleConstants(), 'classes':self.classDefs(), 'footer':self.moduleFooter(), } self._moduleDef = moduleDef return moduleDef def timestamp(self, theTime=None): if not theTime: theTime = time.time() return time.asctime(time.localtime(theTime)) def moduleHeader(self): header = self._moduleShBang + '\n' header += self._moduleEncoding + '\n' if self._moduleHeaderLines: offSet = self.setting('commentOffset') header += ( '#' + ' '*offSet + ('\n#'+ ' '*offSet).join(self._moduleHeaderLines) + '\n' ) return header def moduleDocstring(self): docStr = ('"""' + '\n'.join(self._moduleDocStringLines) + '\n"""\n' ) return docStr def specialVars(self): chunks = [] theVars = self._specialVars keys = theVars.keys() keys.sort() for key in keys: chunks.append(key + ' = ' + repr(theVars[key]) ) return '\n'.join(chunks) def importStatements(self): return '\n'.join(self._importStatements) def moduleConstants(self): return '\n'.join(self._moduleConstants) def classDefs(self): classDefs = [str(klass) for klass in self._finishedClasses() ] return '\n\n'.join(classDefs) def moduleFooter(self): return """ # CHEETAH was developed by Tavis Rudd, Mike Orr, Ian Bicking and Chuck Esterbrook; # with code, advice and input from many other volunteers. # For more information visit http://www.CheetahTemplate.org ################################################## ## if run from command line: if __name__ == '__main__': %(className)s().runAsMainProgram() """ % {'className':self._mainClassName} ################################################## ## Make Compiler an alias for ModuleCompiler Compiler = ModuleCompiler PKt95wŸCheetah/Compiler.pyc; :Cc@s~dZdZddd!ZdkZdkZdkZdklZlZdkZdk Z dk Z dk Z dk Z dk lZdklZd klZlZlZlZlZd klZd klZd klZd efdYZdfdYZdefdYZdefdYZ defdYZ!de!fdYZ"deefdYZ#e#Z$dS(sCompiler classes for Cheetah: ModuleCompiler aka 'Compiler' ClassCompiler MethodCompiler If you are trying to grok this code start with ModuleCompiler.__init__, ModuleCompiler.compile, and ModuleCompiler.__getattr__. Meta-Data ================================================================================ Author: Tavis Rudd Version: $Revision: 1.77 $ Start Date: 2001/09/19 Last Revision Date: $Date: 2005/11/27 03:37:22 $ s!Tavis Rudd s$Revision: 1.77 $i iN(sgetmtimesexists(sVersion(sSettingsManager(sParsers ParseErrors specialVarREs STATIC_CACHEs REFRESH_CACHE(s indentize(s ErrorCatchers(s NameMappersErrorcBstZRS(N(s__name__s __module__(((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pysError&ssGenUtilscBsPtZdZdZdZdZedZdZdZ dZ RS(sAn abstract baseclass for the Compiler classes that provides methods that perform generic utility functions or generate pieces of output code from information passed in by the Parser baseclass. These methods don't do any parsing themselves.cCs|ddjot|d }n|ddjot|d d}n|ddjot|d dd}nw|ddjo t|d ddd}nF|ddjo$t|d dddd }nt|d}|SdS( Nisssmi<shsdiswi(s timeStringsfloatsinterval(sselfs timeStringsinterval((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pysgenTimeInterval1s $cCsx|iii|}|i}h}|do%t|d<|i |d|d then else selseN(sselfsaddIndentingDirectives conditionExprsaddFilteredChunkstrueExprsdedents falseExpr(sselfs conditionExprstrueExprs falseExpr((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys addOneLineIfs     cCs&tidd|}|i|dS(Nselse[ \f\t]+ifselif(sressubsexprsselfsaddReIndentingDirective(sselfsexpr((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pysaddElsescCs|id|ddS(Nsif not (s)(sselfsaddIfsexpr(sselfsexpr((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys addUnlessscCs|i|dS(N(sselfsaddIndentingDirectivesexpr(sselfsexpr((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pysaddTryscCs|i|dS(N(sselfsaddReIndentingDirectivesexpr(sselfsexpr((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys addExceptscCs|i|dS(N(sselfsaddReIndentingDirectivesexpr(sselfsexpr((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys addFinallyscCs|i|dS(N(sselfsaddChunksexpr(sselfsexpr((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys addReturnscCs|it}|ddjo2|d}|o|id|dndSnf|idjo|idSnA|ddjot}|d }n|dd jo t}nx!|i D]}|i |qW|o|i ndS( Nis=isfilter(s)sendis$s:( sselfscommitStrConstsFalses autoIndentsPSPs addWriteChunkslowersdedentsTrues splitlinesslinesaddChunksindent(sselfsPSPs autoIndentsline((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pysaddPSPs(     cCs0ttiddttiddSdS(Nidii'i(sstrsrandoms randrange(sself((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys nextCacheIDscCs |i}|idt}|idt}|idt}|ot |}n|id|}t |_ |i dt|d|i d|i d|d |i d |i|i d |i d |d |i d|i|i d|d |ol|idt|d|i dd|i|i dt|d |i d|in|o:|i d|d|i|i d|in|i d|i|i d|i d|i ddS(NsintervalstestsidsvaryBys$## START CACHE REGION: at line, col s in the source.sRECACHE = Falses region = self._cacheRegions.get(s)sif not region:sregion = CacheRegion()sself._cacheRegions[s ] = regionsRECACHE = Truescache = region.getCache(s#This cache will be refreshed every s seconds.sif (not cache.getRefreshTime())s- or (currentTime() > cache.getRefreshTime()):s$cache.setRefreshTime(currentTime() +sif s:s"if RECACHE or not cache.getData():sorig_trans = transs+trans = cacheCollector = DummyTransaction()s'write = cacheCollector.response().write(sselfs nextCacheIDsIDs cacheInfosgetsNonesintervalstestscustomIDsreprsvaryBysTrues_cacheRegionOpensaddChunksstrslineColsindentsdedentsaddMethDocString(sselfs cacheInfoslineColsintervalsvaryBystestscustomIDsID((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pysstartCacheRegionsF                cCsrt|_|id|id|id|id|i|id|id|iddS(Nstrans = orig_transswrite = trans.response().writes3cache.setData(cacheCollector.response().getvalue())sdel cacheCollectorscache.getData()s## END CACHE REGIONs(sFalsesselfs_cacheRegionOpensaddChunksdedents addWriteChunk(sself((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pysendCacheRegionEs        cCs|io"tt||i|i_n|id|d|i|id|d|i|id|i|id|d|d|idS(Ns if self._errorCatchers.has_key("s"):s*self._errorCatcher = self._errorCatchers["s"]selse:s"] = ErrorCatchers.s(self)( sselfs _templateObjsgetattrs ErrorCatchersserrorCatcherNames _errorCatchersaddChunksindentsdedent(sselfserrorCatcherName((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pyssetErrorCatcherQs "    cCs|o|id|idn|idjo|idn|idt||id|d|i|id|i|id |i|id d |idS( Nsfilter = self._currentFilter = s (self).filtersnonesfilter = self._initialFilters filterName = sif self._filters.has_key("s"):s8filter = self._currentFilter = self._filters[filterName]selse:s@filter = self._currentFilter = \ self._filters[filterName] = s2getattr(self._filtersLib, filterName)(self).filter( sisKlasssselfsaddChunks theFiltersstripslowersreprsindentsdedent(sselfs theFiltersisKlass((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys setFiltercs     (7s__name__s __module__sNones__init__ssettings _setupStates cleanupStates methodNames setMethodNames indentationsindentsdedents methodDefs__str__swrapCodesmethodSignaturessetMethodSignatures methodBodys docStringsaddMethDocStringsaddChunksappendToPrevChunks addWriteChunksaddFilteredChunks addStrConsts addRawTexts_appendToPrevStrConsts_unescapeCheetahVarss_unescapeDirectivesscommitStrConstshandleWSBeforeDirectivesaddMethComments addSilentsTruesaddSets addIncludesaddWhilesaddFors addRepeatsaddIndentingDirectivesaddReIndentingDirectivesaddIfs addOneLineIfsaddElses addUnlesssaddTrys addExcepts addFinallys addReturnsaddPSPs nextCacheIDsstartCacheRegionsendCacheRegionssetErrorCatchers setFilter(((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pysMethodCompilersf                                        0 sAutoMethodCompilercBsMtZdZdZdZdZedZedZdZ RS(NcCs,ti|dtfg|_t|_dS(Nsself(sMethodCompilers _setupStatesselfsNones_argStringListsTrues_streamingEnabled(sself((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys _setupStateys cCsti||i|io|in|id|_|i}g|_|i |ii ||i |i omddfg}|ido#|i ddfddfgnx(|D]\}}|i||qWndS( NsinitialMethIndentLevelstranssNones useNameMappersVFFSLsvalueFromFrameOrSearchListsVFNs valueForName(sMethodCompilers cleanupStatesselfscommitStrConsts_cacheRegionOpensendCacheRegionssettings _indentLevs_methodBodyChunkssmainBodyChunkss_addAutoSetupCodesextends_addAutoCleanupCodes_streamingEnabledsargListsargNamesdefVals addMethArg(sselfsdefValsmainBodyChunkssargNamesargList((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys cleanupState~s"        # cCs6|ioz|id|id|i|id|ido|idn|id|i|idn|id|id|id|id o|id |id n|id o|id n|id|idd|id|iddS(NsOif not trans: trans = self.transaction # is None unless self.awake() was calleds if not trans:strans = DummyTransaction()s autoAssignDummyTransactionToSelfsself.transaction = transsdummyTrans = Trueselse: dummyTrans = Falseswrite = trans.response().writes useNameMappersSL = self._searchLists#globalSetVars = self._globalSetVarss useFilterssfilter = self._currentFilterss#i(s ## START - generated method body(sselfs_streamingEnabledsaddChunksindentssettingsdedent(sself((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys_addAutoSetupCodes,             cCsS|id|idd|id|id|i|iddS(Nss#i(s## END - generated method body(sselfsaddChunksaddStop(sself((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys_addAutoCleanupCodes     cCs|iddS(Ns7return dummyTrans and trans.response().getvalue() or ""(sselfsaddChunk(sselfsexpr((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pysaddStopscCsJt|iddd}|o t|_n|ii||fdS(Ns*ii( smaxsnamesrfinds asteriskPossFalsesselfs_streamingEnableds_argStringListsappendsdefVal(sselfsnamesdefVals asteriskPos((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys addMethArgs cCsg}xP|iD]E}|d}|dtj o|d|d7}n|i|qW|id|idd|idi |dSdS( Niis=sdef s(s, is): ( sargStringChunkssselfs_argStringListsargschunksNonesappends_indents methodNamesjoin(sselfschunksargStringChunkssarg((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pysmethodSignatures  ( s__name__s __module__s _setupStates cleanupStates_addAutoSetupCodes_addAutoCleanupCodesNonesaddStops addMethArgsmethodSignature(((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pysAutoMethodCompilerws      s ClassCompilercBsLtZeZeZdeeedZdZdZ dZ dZ dZ dZ d Zd Zd Zd Zed ZdZdZdZedZdZdZdZdZdZddZdddZdZdZdZ e Z!dZ"dZ#d Z$d!Z%d"Z&RS(#NsrespondcCs||_||_||_||_||_ |i |i |}|id|i||o |ido|i|ndS(Ns,This is the main method generated by CheetahsmonitorSrcFile(ssettingsManagersselfs_settingsManagersfileNames _fileNames classNames _classNamesmainMethodNames_mainMethodNames templateObjs _templateObjs _setupStates_spawnMethodCompilersmethodCompilersaddMethDocStrings_setActiveMethodCompilerssettings_addSourceFileMonitoring(sselfs classNamesmainMethodNames templateObjsfileNamessettingsManagersmethodCompiler((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys__init__s        cCs|ii|SdS(N(sselfs_settingsManagerssettingskey(sselfskey((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pyssettingscCs|ii|o|i|Snjt|i|ot|i|SnC|iot|id|ot|id|Sn t|dS(sVProvide access to the methods and attributes of the MethodCompiler at the top of the activeMethods stack: one-way namespace sharing WARNING: Use .setMethods to assign the attributes of the MethodCompiler from the methods of this class!!! or you will be assigning to attributes of this object instead.iN( sselfs__dict__shas_keysnameshasattrs __class__sgetattrs_activeMethodsListsAttributeError(sselfsname((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys __getattr__s!cCspt|_g|_g|_h|_d|_g|_g|_g|_ t |_ h|_ d|_ h|_dS(NsTemplatei(sNonesselfs _classDefs_activeMethodsLists_finishedMethodsLists _methodsIndexs _baseClasss_classDocStringLiness_generatedAttribss_initMethChunkssTrues _alias__str__s_blockMetaDatas_errorCatcherCounts_placeholderToErrorCatcherMap(sself((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys _setupStates           cCsx(|io|i}|i|qW|i|idjo4|iid|i o|i i |i _ qyn|i d|i dt|idS(Nsresponds__str__ = responds_mainCheetahMethod_for_s= (sselfs_activeMethodsLists_popActiveMethodCompilers methCompilers_swallowMethodCompilers_setupInitMethods_mainMethodNames_generatedAttribssappends _templateObjsresponds__str__s addAttributes _classNamesrepr(sselfs methCompiler((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys cleanupState s    cCs{|idd|i}|id|id|ix|iD]}|i|qCW|i |i |dddS(Ns__init__sklasss def __init__(self, *args, **KWs)s%s.__init__(self, *args, **KWs)sposi( sselfs_spawnMethodCompilersmethodCompilerClassForInits__init__ssetMethodSignaturesaddChunks _baseClasss_initMethChunksschunks cleanupStates_swallowMethodCompiler(sselfschunks__init__((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys_setupInitMethods    cCs|idt||idtt||io0t|id|t|idt|n|idd|i |idt d|id |i d |i |i dS( Nsself._filePath = sself._fileMtime = s _filePaths _fileMtimesif exists(self._filePath) and s+getmtime(self._filePath) > self._fileMtime:s-self.compile(file=self._filePath, moduleName=s)s0write(getattr(self, self._mainCheetahMethod_for_s)(trans=trans))(sselfsaddChunkToInitsreprsfileNamesstrsgetmtimes _templateObjssetattrsaddChunksindents classNames _classNamesaddStopsdedent(sselfsfileName((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys_addSourceFileMonitoring s   cCs ||_dS(N(snamesselfs _className(sselfsname((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys setClassName5scCs |iSdS(N(sselfs _className(sself((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys className8scCs ||_dS(N(s baseClassNamesselfs _baseClass(sselfs baseClassName((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys setBaseClass;scCs|i|i}|i|||i|s     cCsJ|tjo |i}n||d|d|i}||i|<|SdS(Ns classCompilers templateObj(sklasssNonesselfsmethodCompilerClasss methodNames _templateObjsmethodCompilers _methodsIndex(sselfs methodNamesklasssmethodCompiler((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys_spawnMethodCompilerRs    cCs|ii|dS(N(sselfs_activeMethodsListsappendsmethodCompiler(sselfsmethodCompiler((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys_setActiveMethodCompilerYscCs|idSdS(Ni(sselfs_activeMethodsList(sself((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys_getActiveMethodCompiler\scCs|iiSdS(N(sselfs_activeMethodsListspop(sself((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys_popActiveMethodCompiler_scCsw|i|tjo|ii|n|ii|||io|i djo|ii |n|SdS(Ns__init__( smethodCompilers cleanupStatespossNonesselfs_finishedMethodsListsappendsinserts _templateObjs methodNames_bindCompiledMethod(sselfsmethodCompilerspos((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys_swallowMethodCompilerbs  cCsT|i|}|i|x$|D]\}}|i||q#W|i |dS(N( sselfs_spawnMethodCompilers methodNamesmethodCompilers_setActiveMethodCompilersargsListsargNamesdefVals addMethArgsaddMethDocStrings parserComment(sselfs methodNamesargsLists parserCommentsdefValsmethodCompilersargName((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pysstartMethodDefns   cCs |iSdS(N(sselfs_finishedMethodsList(sself((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys_finishedMethodsxscCs |ii|idddS(Ns%s%%(sselfs_classDocStringLinessappendslinesreplace(sselfsline((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pysaddClassDocString}scCs|ii|dS(N(sselfs_initMethChunkssappendschunk(sselfschunk((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pysaddChunkToInitscBsw|iddjp|iddjoe|ddn|ii||iod|idUndS(NsVFN(isVFFSL(sInvalid #attr directive.s/ It should only contain simple Python literals.sself._templateObj.(s attribExprsfinds ParseErrorsselfs_generatedAttribssappends _templateObjsstrip(sselfs attribExpr((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys addAttributes , sinicCsP|djo d}nd}d|d|iddd}|i|dS(NspythonsupdateSettingsFromPySrcStrsupdateSettingsFromConfigStrsself.s('''s'''s''')(s settingsTypesreaders settingsStrsreplaces settingsCodesselfsaddChunkToInit(sselfs settingsStrs settingsTypes settingsCodesreader((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pysaddSettingsToInits   "scCsz|ii|oH|i|}|id o"|i|idt|n|Sn|i d7_ dt|i }||i|<|i |dt }|id|d|id|d t|d |id |i|id |d |i|id|i|idt|dt|dt|d|i|i||SdS(NsoutputRowColCommentssplus at line, col is__errorCatchersklasssdef s(self, localsDict={})sGenerated from s at line, col s.stry:sreturn eval('''s''', globals(), localsDict)s*except self._errorCatcher.exceptions(), e:s0return self._errorCatcher.warn(exc_val=e, code= s , rawCode= s , lineCol=s)(sselfs_placeholderToErrorCatcherMapshas_keysrawCodes methodNamessettings _methodsIndexsaddMethDocStringsstrslineCols_errorCatcherCounts_spawnMethodCompilersMethodCompilers catcherMethssetMethodSignaturesaddChunksindents codeChunksdedentsreprs cleanupStates_swallowMethodCompiler(sselfs codeChunksrawCodeslineCols methodNames catcherMeth((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pysaddErrorCatcherCalls* " #     7  cCs'|i|i}|i|dS(N(sselfscommitStrConsts_popActiveMethodCompilers methCompilers_swallowMethodCompiler(sselfs methCompiler((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pyscloseDefs  cCs|i|i}|i}|ido0|id}|i|d||dn|i|d|d}|i |dS(NsincludeBlockMarkerssblockMarkerEndiisself.s (trans=trans)( sselfscommitStrConsts_popActiveMethodCompilers methCompilers methodNamessettings endMarkers addStrConsts_swallowMethodCompilers codeChunksaddChunk(sselfs endMarkers methodNames methCompilers codeChunk((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys closeBlocks   ! cCs#|io |iSn |iSdS(N(sselfs _classDefs wrapClassDef(sself((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pysclassDefs  c Cs|id|i|id|id}|i|i|dd|dd|i|dd|dd|if }di |}||_ |SdS( Nss defDocStrMsgsindentationSteps#i2s## GENERATED METHODSs s## GENERATED ATTRIBUTES( sselfsaddClassDocStringssettingsindsclassSignaturesclassDocstrings methodDefss attributessclassDefChunkssjoinsclassDefs _classDef(sselfsindsclassDefChunkssclassDef((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys wrapClassDefs T  cCsd|i|ifSdS(Ns class %s(%s):(sselfs classNames _baseClass(sself((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pysclassSignaturescCs>|id}ddi|idhd|<}|SdS(NsindentationSteps%(ind)s""" %(ind)ss %(ind)ss %(ind)s""" sind(sselfssettingsindsjoins_classDocStringLinessdocStr(sselfsindsdocStr((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pysclassDocstrings'cCsDgi}|iD]}|t|q~}di|SdS(Ns (sappends_[1]sselfs_finishedMethodssmethGensstrs methodDefssjoin(sselfs_[1]s methodDefssmethGen((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys methodDefss3cCsNgi}|iD]#}||idt|q~}di|SdS(NsindentationSteps ( sappends_[1]sselfs_generatedAttribssattribssettingsstrsattribssjoin(sselfsattribss_[1]sattrib((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys attributess=('s__name__s __module__sAutoMethodCompilersmethodCompilerClasssMethodCompilersmethodCompilerClassForInitsNones__init__ssettings __getattr__s _setupStates cleanupStates_setupInitMethods_addSourceFileMonitorings setClassNames classNames setBaseClassssetMainMethodNames_spawnMethodCompilers_setActiveMethodCompilers_getActiveMethodCompilers_popActiveMethodCompilers_swallowMethodCompilersstartMethodDefs_finishedMethodssaddClassDocStringsaddChunkToInits addAttributesaddSettingsToInitsaddErrorCatcherCallscloseDefs closeBlocksclassDefs__str__s wrapClassDefsclassSignaturesclassDocstrings methodDefss attributes(((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys ClassCompilersD                "       sAutoClassCompilercBstZRS(N(s__name__s __module__(((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pysAutoClassCompilerssModuleCompilercBstZeZeZeededeedZdZdZ dZ dZ eddZ d Z d Zd Zd Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!dZ"dZ#e#Z$d Z%ed!Z&d"Z'd#Z(d$Z)d%Z*d&Z+d'Z,d(Z-RS()Ns GenTemplatesrespondc CsXti||o|i|nti o!tid|i dt n||_ t |_ ||_| o ||_n ||_||_t|_t|_|o|otdnt|tipt|tioDt|}|i }|i!||_t"i#i$||_n8t%|do|i }n|otdn|ioFt"i#i&|i\|_'|_(t"i#i)|i(\|_*|_+nt|t,p t|t- ot,|}n|djotidn|i.dd jot/|}n|i0|d |id ||_1|i2dS( Ns You don't have the C version of NameMapper installed! I'm disabling Cheetah's useStackFrames option as it is painfully slow with the Python version of NameMapper. You should get a copy of Cheetah with the compiled C version of NameMapper.suseStackFramess-Cannot compile from a source string AND file.sreads='file' argument must be a filename string or file-like objectss,You supplied an empty string for the source!s#indentisfilenamescompiler(3sSettingsManagers__init__sselfssettingssupdateSettingss NameMappers C_VERSIONswarningsswarns setSettingsFalses templateObjs _templateObjs _compileds moduleNames _moduleNames mainClassNames_mainClassNamesmainMethodNames_mainMethodNamesNones _filePaths _fileMtimessourcesfiles TypeErrors isinstancestypess StringTypes UnicodeTypesopensfsreadsclosesosspathsgetmtimeshasattrssplits _fileDirNames _fileBaseNamessplitexts_fileBaseNameRoots_fileBaseNameExtsstrsunicodesfinds indentizes parserClasss_parsers_setupCompilerState( sselfssourcesfiles moduleNames mainClassNamesmainMethodNames templateObjssettingssf((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys__init__sL           &     !%! !cCs|ii|o|i|Snjt|i|ot|i|SnC|iot|id|ot|id|Sn t|dS(s<Provide one-way access to the methods and attributes of the ClassCompiler, and thereby the MethodCompilers as well. WARNING: Use .setMethods to assign the attributes of the ClassCompiler from the methods of this class!!! or you will be assigning to attributes of this object instead.iN( sselfs__dict__shas_keysnameshasattrs __class__sgetattrs_activeClassesListsAttributeError(sselfsname((s5build/bdist.darwin-8.7.1-i386/egg/Cheetah/Compiler.pys __getattr__`s!cCs5hddd<dd<dt<dt<dt<d t<d t<d t<d t<d t<dt<dt<dd<dt<dd<dt<dt<dddf<dddf<dd<ddd d!g<d"d#<d$d%<d&d'<d(d)<d*d+<d,d+<d-d.<d/d0<}|i|dS(1NsindentationSteps isinitialMethIndentLevelismonitorSrcFiles useNameMappers useSearchListsuseAutocallingsuseStackFramessuseErrorCatchersalwaysFilterNones useFilterssincludeRawExprInFilterArgss autoAssignDummyTransactionToSelfs commentOffsetisreprShortStrConstantssreprNewlineThresholdisoutputRowColCommentssincludeBlockMarkerssblockMarkerStarts sblockMarkerEnds