"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "Cheetah/Compiler.py" between
cheetah3-3.1.0.tar.gz and cheetah3-3.2.0.tar.gz

About: Cheetah3 is a template engine and code generation tool for e.g. for Web development or Java, SQL, LaTeX, form email ... (written in Python).

Compiler.py  (cheetah3-3.1.0):Compiler.py  (cheetah3-3.2.0)
skipping to change at line 27 skipping to change at line 27
import random import random
import warnings import warnings
import copy import copy
import codecs import codecs
from Cheetah.Version import Version, VersionTuple from Cheetah.Version import Version, VersionTuple
from Cheetah.SettingsManager import SettingsManager from Cheetah.SettingsManager import SettingsManager
from Cheetah.Utils.Indenter import indentize # an undocumented preprocessor from Cheetah.Utils.Indenter import indentize # an undocumented preprocessor
from Cheetah import NameMapper from Cheetah import NameMapper
from Cheetah.Parser import Parser, ParseError, specialVarRE, \ from Cheetah.Parser import Parser, ParseError, specialVarRE, \
STATIC_CACHE, REFRESH_CACHE, SET_GLOBAL, SET_MODULE, \ STATIC_CACHE, REFRESH_CACHE, SET_GLOBAL, SET_MODULE, \
unicodeDirectiveRE, encodingDirectiveRE, escapedNewlineRE unicodeDirectiveRE, encodingDirectiveRE, escapedNewlineRE
from Cheetah.compat import string_type, unicode from Cheetah.compat import PY2, string_type, unicode
from Cheetah.NameMapper import valueForName, valueFromSearchList, \ from Cheetah.NameMapper import valueForName, valueFromSearchList, \
valueFromFrameOrSearchList valueFromFrameOrSearchList
VFFSL = valueFromFrameOrSearchList VFFSL = valueFromFrameOrSearchList
VFSL = valueFromSearchList VFSL = valueFromSearchList
VFN = valueForName VFN = valueForName
currentTime = time.time currentTime = time.time
class Error(Exception): class Error(Exception):
pass pass
skipping to change at line 147 skipping to change at line 147
perform generic utility functions or generate pieces of output code from perform generic utility functions or generate pieces of output code from
information passed in by the Parser baseclass. These methods don't do any information passed in by the Parser baseclass. These methods don't do any
parsing themselves. parsing themselves.
""" """
def genTimeInterval(self, timeString): def genTimeInterval(self, timeString):
# #@@ TR: need to add some error handling here # #@@ TR: need to add some error handling here
if timeString[-1] == 's': if timeString[-1] == 's':
interval = float(timeString[:-1]) interval = float(timeString[:-1])
elif timeString[-1] == 'm': elif timeString[-1] == 'm':
interval = float(timeString[:-1])*60 interval = float(timeString[:-1])*60 # noqa: E226,E501 missing whit espace around operator
elif timeString[-1] == 'h': elif timeString[-1] == 'h':
interval = float(timeString[:-1])*60*60 interval = float(timeString[:-1])*60*60 # noqa: E226,E501 missing w hitespace around operator
elif timeString[-1] == 'd': elif timeString[-1] == 'd':
interval = float(timeString[:-1])*60*60*24 interval = float(timeString[:-1])*60*60*24 # noqa: E226,E501 missin g whitespace around operator
elif timeString[-1] == 'w': elif timeString[-1] == 'w':
interval = float(timeString[:-1])*60*60*24*7 interval = float(timeString[:-1])*60*60*24*7 # noqa: E226,E501 miss ing whitespace around operator
else: # default to minutes else: # default to minutes
interval = float(timeString)*60 interval = float(timeString)*60 # noqa: E226,E501 missing whitespac e around operator
return interval return interval
def genCacheInfo(self, cacheTokenParts): def genCacheInfo(self, cacheTokenParts):
"""Decipher a placeholder cachetoken """Decipher a placeholder cachetoken
""" """
cacheInfo = {} cacheInfo = {}
if cacheTokenParts['REFRESH_CACHE']: if cacheTokenParts['REFRESH_CACHE']:
cacheInfo['type'] = REFRESH_CACHE cacheInfo['type'] = REFRESH_CACHE
cacheInfo['interval'] = \ cacheInfo['interval'] = \
self.genTimeInterval(cacheTokenParts['interval']) self.genTimeInterval(cacheTokenParts['interval'])
skipping to change at line 293 skipping to change at line 293
defaultUseAC = self.setting('useAutocalling') defaultUseAC = self.setting('useAutocalling')
useSearchList = self.setting('useSearchList') useSearchList = self.setting('useSearchList')
nameChunks.reverse() nameChunks.reverse()
name, useAC, remainder = nameChunks.pop() name, useAC, remainder = nameChunks.pop()
if not useSearchList: if not useSearchList:
firstDotIdx = name.find('.') firstDotIdx = name.find('.')
if firstDotIdx != -1 and firstDotIdx < len(name): if firstDotIdx != -1 and firstDotIdx < len(name):
beforeFirstDot = name[:firstDotIdx] beforeFirstDot = name[:firstDotIdx]
afterDot = name[firstDotIdx+1:] afterDot = name[firstDotIdx+1:] # noqa: E226,E501 missing white
pythonCode = ('VFN(' + beforeFirstDot + space around operator
',"' + afterDot + pythonCode = ('VFN(' + beforeFirstDot
'",' + repr(defaultUseAC and useAC) + ')' + ',"' + afterDot
+ '",' + repr(defaultUseAC and useAC) + ')'
+ remainder) + remainder)
else: else:
pythonCode = name+remainder pythonCode = name + remainder
elif self.setting('useStackFrames'): elif self.setting('useStackFrames'):
pythonCode = ('VFFSL(SL,' pythonCode = ('VFFSL(SL,'
'"' + name + '",' '"' + name + '",'
+ repr(defaultUseAC and useAC) + ')' + repr(defaultUseAC and useAC) + ')'
+ remainder) + remainder)
else: else:
pythonCode = ('VFSL([locals()]+SL+[globals(), builtin],' pythonCode = ('VFSL([locals()]+SL+[globals(), builtin],'
'"' + name + '",' '"' + name + '",'
+ repr(defaultUseAC and useAC) + ')' + repr(defaultUseAC and useAC) + ')'
+ remainder) + remainder)
## ##
while nameChunks: while nameChunks:
name, useAC, remainder = nameChunks.pop() name, useAC, remainder = nameChunks.pop()
pythonCode = ('VFN(' + pythonCode + pythonCode = ('VFN(' + pythonCode
',"' + name + + ',"' + name
'",' + repr(defaultUseAC and useAC) + ')' + '",' + repr(defaultUseAC and useAC) + ')'
+ remainder) + remainder)
return pythonCode return pythonCode
################################################## ##################################################
# METHOD COMPILERS # METHOD COMPILERS
class MethodCompiler(GenUtils): class MethodCompiler(GenUtils):
def __init__(self, methodName, classCompiler, def __init__(self, methodName, classCompiler,
initialMethodComment=None, initialMethodComment=None,
decorators=None): decorators=None):
skipping to change at line 416 skipping to change at line 416
def setMethodSignature(self, signature): def setMethodSignature(self, signature):
self._methodSignature = signature self._methodSignature = signature
def methodBody(self): def methodBody(self):
return ''.join(self._methodBodyChunks) return ''.join(self._methodBodyChunks)
def docString(self): def docString(self):
if not self._docStringLines: if not self._docStringLines:
return '' return ''
ind = self._indent*2 ind = self._indent*2 # noqa: E226 missing whitespace around operator
docStr = (ind + '"""\n' + ind + docStr = (ind + '"""\n' + ind
('\n' + ind).join( + ('\n' + ind).join([ln.replace('"""', "'''")
[ln.replace('"""', "'''") for ln in self._docStringLines])
for ln in self._docStringLines])
+ '\n' + ind + '"""\n') + '\n' + ind + '"""\n')
return docStr return docStr
# methods for adding code # methods for adding code
def addMethDocString(self, line): def addMethDocString(self, line):
self._docStringLines.append(line.replace('%', '%%')) self._docStringLines.append(line.replace('%', '%%'))
def addChunk(self, chunk): def addChunk(self, chunk):
self.commitStrConst() self.commitStrConst()
chunk = "\n" + self.indentation() + chunk chunk = "\n" + self.indentation() + chunk
skipping to change at line 490 skipping to change at line 489
self._pendingStrConstChunks = [] self._pendingStrConstChunks = []
if not strConst: if not strConst:
return return
reprstr = repr(strConst) reprstr = repr(strConst)
i = 0 i = 0
out = [] out = []
if reprstr.startswith('u'): if reprstr.startswith('u'):
i = 1 i = 1
out = ['u'] out = ['u']
body = escapedNewlineRE.sub('\\1\n', reprstr[i+1:-1]) body = escapedNewlineRE.sub('\\1\n', reprstr[i+1:-1]) # noqa: E226,E501 missing whitespace around operator
if reprstr[i] == "'": if reprstr[i] == "'":
out.append("'''") out.append("'''")
out.append(body) out.append(body)
out.append("'''") out.append("'''")
else: else:
out.append('"""') out.append('"""')
out.append(body) out.append(body)
out.append('"""') out.append('"""')
self.addWriteChunk(''.join(out)) self.addWriteChunk(''.join(out))
def handleWSBeforeDirective(self): def handleWSBeforeDirective(self):
"""Truncate the pending strCont to the beginning of the current line. """Truncate the pending strCont to the beginning of the current line.
""" """
if self._pendingStrConstChunks: if self._pendingStrConstChunks:
src = self._pendingStrConstChunks[-1] src = self._pendingStrConstChunks[-1]
BOL = max(src.rfind('\n')+1, src.rfind('\r')+1, 0) BOL = max(src.rfind('\n') + 1, src.rfind('\r') + 1, 0)
if BOL < len(src): if BOL < len(src):
self._pendingStrConstChunks[-1] = src[:BOL] self._pendingStrConstChunks[-1] = src[:BOL]
def isErrorCatcherOn(self): def isErrorCatcherOn(self):
return self._isErrorCatcherOn return self._isErrorCatcherOn
def turnErrorCatcherOn(self): def turnErrorCatcherOn(self):
self._isErrorCatcherOn = True self._isErrorCatcherOn = True
def turnErrorCatcherOff(self): def turnErrorCatcherOff(self):
skipping to change at line 529 skipping to change at line 528
# @@TR: consider merging the next two methods into one # @@TR: consider merging the next two methods into one
def addStrConst(self, strConst): def addStrConst(self, strConst):
self._appendToPrevStrConst(strConst) self._appendToPrevStrConst(strConst)
def addRawText(self, text): def addRawText(self, text):
self.addStrConst(text) self.addStrConst(text)
def addMethComment(self, comm): def addMethComment(self, comm):
offSet = self.setting('commentOffset') offSet = self.setting('commentOffset')
self.addChunk('#' + ' '*offSet + comm) self.addChunk('#' + ' '*offSet + comm) # noqa: E226,E501 missing whites pace around operator
def addPlaceholder(self, expr, filterArgs, rawPlaceholder, def addPlaceholder(self, expr, filterArgs, rawPlaceholder,
cacheTokenParts, lineCol, cacheTokenParts, lineCol,
silentMode=False): silentMode=False):
cacheInfo = self.genCacheInfo(cacheTokenParts) cacheInfo = self.genCacheInfo(cacheTokenParts)
if cacheInfo: if cacheInfo:
cacheInfo['ID'] = repr(rawPlaceholder)[1:-1] cacheInfo['ID'] = repr(rawPlaceholder)[1:-1]
self.startCacheRegion(cacheInfo, lineCol, self.startCacheRegion(cacheInfo, lineCol,
rawPlaceholder=rawPlaceholder) rawPlaceholder=rawPlaceholder)
skipping to change at line 598 skipping to change at line 597
LVALUE = \ LVALUE = \
'self._CHEETAH__globalSetVars["' + primary + '"]' + secondary 'self._CHEETAH__globalSetVars["' + primary + '"]' + secondary
expr = LVALUE + ' ' + OP + ' ' + RVALUE.strip() expr = LVALUE + ' ' + OP + ' ' + RVALUE.strip()
if setStyle is SET_MODULE: if setStyle is SET_MODULE:
self._moduleCompiler.addModuleGlobal(expr) self._moduleCompiler.addModuleGlobal(expr)
else: else:
self.addChunk(expr) self.addChunk(expr)
def addInclude(self, sourceExpr, includeFrom, isRaw): def addInclude(self, sourceExpr, includeFrom, isRaw):
self.addChunk('self._handleCheetahInclude(' + sourceExpr + self.addChunk('self._handleCheetahInclude(' + sourceExpr
', trans=trans, ' + + ', trans=trans, '
'includeFrom="' + includeFrom + '", raw=' + + 'includeFrom="' + includeFrom + '", raw='
repr(isRaw) + ')') + repr(isRaw) + ')')
def addWhile(self, expr, lineCol=None): def addWhile(self, expr, lineCol=None):
self.addIndentingDirective(expr, lineCol=lineCol) self.addIndentingDirective(expr, lineCol=lineCol)
def addFor(self, expr, lineCol=None): def addFor(self, expr, lineCol=None):
self.addIndentingDirective(expr, lineCol=lineCol) self.addIndentingDirective(expr, lineCol=lineCol)
def addRepeat(self, expr, lineCol=None): def addRepeat(self, expr, lineCol=None):
# the _repeatCount stuff here allows nesting of #repeat directives # the _repeatCount stuff here allows nesting of #repeat directives
self._repeatCount = getattr(self, "_repeatCount", -1) + 1 self._repeatCount = getattr(self, "_repeatCount", -1) + 1
skipping to change at line 679 skipping to change at line 678
def addClosure(self, functionName, argsList, parserComment): def addClosure(self, functionName, argsList, parserComment):
argStringChunks = [] argStringChunks = []
for arg in argsList: for arg in argsList:
chunk = arg[0] chunk = arg[0]
if arg[1] is not None: if arg[1] is not None:
chunk += '=' + arg[1] chunk += '=' + arg[1]
argStringChunks.append(chunk) argStringChunks.append(chunk)
signature = \ signature = \
"def " + functionName + "(" + ','.join(argStringChunks) + "):" "def " + functionName + "(" + ','.join(argStringChunks) + "):"
self.addIndentingDirective(signature) self.addIndentingDirective(signature)
self.addChunk('#'+parserComment) self.addChunk('#' + parserComment)
def addTry(self, expr, lineCol=None): def addTry(self, expr, lineCol=None):
self.addIndentingDirective(expr, lineCol=lineCol) self.addIndentingDirective(expr, lineCol=lineCol)
def addExcept(self, expr, dedent=True, lineCol=None): def addExcept(self, expr, dedent=True, lineCol=None):
self.addReIndentingDirective(expr, dedent=dedent, lineCol=lineCol) self.addReIndentingDirective(expr, dedent=dedent, lineCol=lineCol)
def addFinally(self, expr, dedent=True, lineCol=None): def addFinally(self, expr, dedent=True, lineCol=None):
self.addReIndentingDirective(expr, dedent=dedent, lineCol=lineCol) self.addReIndentingDirective(expr, dedent=dedent, lineCol=lineCol)
skipping to change at line 756 skipping to change at line 755
elif PSP[-1] == ':': elif PSP[-1] == ':':
autoIndent = True autoIndent = True
for line in PSP.splitlines(): for line in PSP.splitlines():
self.addChunk(line) self.addChunk(line)
if autoIndent: if autoIndent:
self.indent() self.indent()
def nextCacheID(self): def nextCacheID(self):
return ('_'+str(random.randrange(100, 999)) return ('_' + str(random.randrange(100, 999))
+ str(random.randrange(10000, 99999))) + str(random.randrange(10000, 99999)))
def startCacheRegion(self, cacheInfo, lineCol, rawPlaceholder=None): def startCacheRegion(self, cacheInfo, lineCol, rawPlaceholder=None):
# @@TR: we should add some runtime logging to this # @@TR: we should add some runtime logging to this
ID = self.nextCacheID() ID = self.nextCacheID()
interval = cacheInfo.get('interval', None) interval = cacheInfo.get('interval', None)
test = cacheInfo.get('test', None) test = cacheInfo.get('test', None)
customID = cacheInfo.get('id', None) customID = cacheInfo.get('id', None)
skipping to change at line 851 skipping to change at line 850
self.addChunk('write = trans.response().write') self.addChunk('write = trans.response().write')
self.addChunk( self.addChunk(
'_cacheData = _cacheCollector_%(ID)s.response().getvalue()' '_cacheData = _cacheCollector_%(ID)s.response().getvalue()'
% locals()) % locals())
self.addChunk('_cacheItem_%(ID)s.setData(_cacheData)' % locals()) self.addChunk('_cacheItem_%(ID)s.setData(_cacheData)' % locals())
self.addWriteChunk('_cacheData') self.addWriteChunk('_cacheData')
self.addChunk('del _cacheData') self.addChunk('del _cacheData')
self.addChunk('del _cacheCollector_%(ID)s' % locals()) self.addChunk('del _cacheCollector_%(ID)s' % locals())
self.addChunk('del _orig_trans%(ID)s' % locals()) self.addChunk('del _orig_trans%(ID)s' % locals())
self.dedent() self.dedent()
self.addChunk('## END CACHE REGION: '+ID) self.addChunk('## END CACHE REGION: ' + ID)
self.addChunk('') self.addChunk('')
def nextCallRegionID(self): def nextCallRegionID(self):
return self.nextCacheID() return self.nextCacheID()
def startCallRegion(self, functionName, args, lineCol, regionTitle='CALL'): def startCallRegion(self, functionName, args, lineCol, regionTitle='CALL'):
class CallDetails(object): class CallDetails(object):
pass pass
callDetails = CallDetails() callDetails = CallDetails()
callDetails.ID = ID = self.nextCallRegionID() callDetails.ID = ID = self.nextCallRegionID()
skipping to change at line 924 skipping to change at line 923
self.addChunk('del _wasBuffering%(ID)s' % locals()) self.addChunk('del _wasBuffering%(ID)s' % locals())
self.addChunk('del _orig_trans%(ID)s' % locals()) self.addChunk('del _orig_trans%(ID)s' % locals())
if not callDetails.usesKeywordArgs: if not callDetails.usesKeywordArgs:
reset() reset()
self.addChunk( self.addChunk(
'_callArgVal%(ID)s = ' '_callArgVal%(ID)s = '
'_callCollector%(ID)s.response().getvalue()' % locals()) '_callCollector%(ID)s.response().getvalue()' % locals())
self.addChunk('del _callCollector%(ID)s' % locals()) self.addChunk('del _callCollector%(ID)s' % locals())
if initialKwArgs: if initialKwArgs:
initialKwArgs = ', '+initialKwArgs initialKwArgs = ', ' + initialKwArgs
self.addFilteredChunk( self.addFilteredChunk(
'%(functionName)s(_callArgVal%(ID)s%(initialKwArgs)s)' '%(functionName)s(_callArgVal%(ID)s%(initialKwArgs)s)'
% locals()) % locals())
self.addChunk('del _callArgVal%(ID)s' % locals()) self.addChunk('del _callArgVal%(ID)s' % locals())
else: else:
if initialKwArgs: if initialKwArgs:
initialKwArgs = initialKwArgs+', ' initialKwArgs = initialKwArgs + ', '
self._endCallArg() self._endCallArg()
reset() reset()
self.addFilteredChunk( self.addFilteredChunk(
'%(functionName)s(%(initialKwArgs)s**_callKws%(ID)s)' '%(functionName)s(%(initialKwArgs)s**_callKws%(ID)s)'
% locals()) % locals())
self.addChunk('del _callKws%(ID)s' % locals()) self.addChunk('del _callKws%(ID)s' % locals())
self.addChunk('## END %(regionTitle)s REGION: ' % locals() + ID self.addChunk('## END %(regionTitle)s REGION: ' % locals() + ID
+ ' of ' + functionName + ' of ' + functionName
+ ' at line %s, col %s' % lineCol + ' in the source.') + ' at line %s, col %s' % lineCol + ' in the source.')
self.addChunk('') self.addChunk('')
skipping to change at line 989 skipping to change at line 988
self.addChunk('del _captureCollector%(ID)s' % locals()) self.addChunk('del _captureCollector%(ID)s' % locals())
self.addChunk('del _wasBuffering%(ID)s' % locals()) self.addChunk('del _wasBuffering%(ID)s' % locals())
def setErrorCatcher(self, errorCatcherName): def setErrorCatcher(self, errorCatcherName):
self.turnErrorCatcherOn() self.turnErrorCatcherOn()
self.addChunk( self.addChunk(
'if "' + errorCatcherName + '" in self._CHEETAH__errorCatchers:') 'if "' + errorCatcherName + '" in self._CHEETAH__errorCatchers:')
self.indent() self.indent()
self.addChunk( self.addChunk(
'self._CHEETAH__errorCatcher = self._CHEETAH__errorCatchers["' + 'self._CHEETAH__errorCatcher = self._CHEETAH__errorCatchers["'
errorCatcherName + '"]') + errorCatcherName + '"]')
self.dedent() self.dedent()
self.addChunk('else:') self.addChunk('else:')
self.indent() self.indent()
self.addChunk( self.addChunk(
'self._CHEETAH__errorCatcher = self._CHEETAH__errorCatchers["' 'self._CHEETAH__errorCatcher = self._CHEETAH__errorCatchers["'
+ errorCatcherName + '"] = ErrorCatchers.' + errorCatcherName + '"] = ErrorCatchers.'
+ errorCatcherName + '(self)' + errorCatcherName + '(self)'
) )
self.dedent() self.dedent()
def nextFilterRegionID(self): def nextFilterRegionID(self):
return self.nextCacheID() return self.nextCacheID()
def setTransform(self, transformer, isKlass): def setTransform(self, transformer, isKlass):
self.addChunk('trans = TransformerTransaction()') self.addChunk('trans = TransformerTransaction()')
self.addChunk('trans._response = trans.response()') self.addChunk('trans._response = trans.response()')
self.addChunk('trans._response._filter = %s' % transformer) self.addChunk('trans._response._filter = %s' % transformer)
self.addChunk('write = trans._response.write') self.addChunk('write = trans._response.write')
skipping to change at line 1161 skipping to change at line 1160
elif not self.isClassMethod() and not self.isStaticMethod(): elif not self.isClassMethod() and not self.isStaticMethod():
self.addChunk('SL = self._CHEETAH__searchList') self.addChunk('SL = self._CHEETAH__searchList')
else: else:
self.addChunk('SL = [KWS]') self.addChunk('SL = [KWS]')
if self.setting('useFilters'): if self.setting('useFilters'):
if self.isClassMethod() or self.isStaticMethod(): if self.isClassMethod() or self.isStaticMethod():
self.addChunk('_filter = lambda x, **kwargs: unicode(x)') self.addChunk('_filter = lambda x, **kwargs: unicode(x)')
else: else:
self.addChunk('_filter = self._CHEETAH__currentFilter') self.addChunk('_filter = self._CHEETAH__currentFilter')
self.addChunk('') self.addChunk('')
self.addChunk("#"*40) self.addChunk("#"*40) # noqa: E226 missing whitespace around operator
self.addChunk('## START - generated method body') self.addChunk('## START - generated method body')
self.addChunk('') self.addChunk('')
def _addAutoCleanupCode(self): def _addAutoCleanupCode(self):
self.addChunk('') self.addChunk('')
self.addChunk("#"*40) self.addChunk("#"*40) # noqa: E226 missing whitespace around operator
self.addChunk('## END - generated method body') self.addChunk('## END - generated method body')
self.addChunk('') self.addChunk('')
if not self._isGenerator: if not self._isGenerator:
self.addStop() self.addStop()
self.addChunk('') self.addChunk('')
def addStop(self, expr=None): def addStop(self, expr=None):
self.addChunk( self.addChunk(
'return _dummyTrans and trans.response().getvalue() or ""') 'return _dummyTrans and trans.response().getvalue() or ""')
skipping to change at line 1201 skipping to change at line 1200
if arg[1] is not None: if arg[1] is not None:
chunk += '=' + arg[1] chunk += '=' + arg[1]
argStringChunks.append(chunk) argStringChunks.append(chunk)
argString = (', ').join(argStringChunks) argString = (', ').join(argStringChunks)
output = [] output = []
if self._decorators: if self._decorators:
output.append(''.join([self._indent + decorator + '\n' output.append(''.join([self._indent + decorator + '\n'
for decorator in self._decorators])) for decorator in self._decorators]))
output.append(self._indent + "def " output.append(self._indent + "def "
+ self.methodName() + "(" + + self.methodName() + "("
argString + "):\n\n") + argString + "):\n\n")
return ''.join(output) return ''.join(output)
################################################## ##################################################
# CLASS COMPILERS # CLASS COMPILERS
_initMethod_initCheetah = """\ _initMethod_initCheetah = """\
if not self._CHEETAH__instanceInitialized: if not self._CHEETAH__instanceInitialized:
cheetahKWArgs = {} cheetahKWArgs = {}
allowedKWs = 'searchList namespaces filter filtersLib errorCatcher'.split() allowedKWs = 'searchList namespaces filter filtersLib errorCatcher'.split()
for k,v in KWs.items(): for k,v in KWs.items():
if k in allowedKWs: cheetahKWArgs[k] = v if k in allowedKWs: cheetahKWArgs[k] = v
self._initCheetahInstance(**cheetahKWArgs) self._initCheetahInstance(**cheetahKWArgs)
""".replace('\n', '\n'+' '*8) """.replace('\n', '\n' + ' '*8) # noqa: E226,E501 missing whitespace around ope rator
class ClassCompiler(GenUtils): class ClassCompiler(GenUtils):
methodCompilerClass = AutoMethodCompiler methodCompilerClass = AutoMethodCompiler
methodCompilerClassForInit = MethodCompiler methodCompilerClassForInit = MethodCompiler
def __init__(self, className, mainMethodName='respond', def __init__(self, className, mainMethodName='respond',
moduleCompiler=None, moduleCompiler=None,
fileName=None, fileName=None,
settingsManager=None): settingsManager=None):
skipping to change at line 1288 skipping to change at line 1287
'_CHEETAH_genTime = __CHEETAH_genTime__') '_CHEETAH_genTime = __CHEETAH_genTime__')
self._generatedAttribs.append( self._generatedAttribs.append(
'_CHEETAH_genTimestamp = __CHEETAH_genTimestamp__') '_CHEETAH_genTimestamp = __CHEETAH_genTimestamp__')
self._generatedAttribs.append('_CHEETAH_src = __CHEETAH_src__') self._generatedAttribs.append('_CHEETAH_src = __CHEETAH_src__')
self._generatedAttribs.append( self._generatedAttribs.append(
'_CHEETAH_srcLastModified = __CHEETAH_srcLastModified__') '_CHEETAH_srcLastModified = __CHEETAH_srcLastModified__')
if self.setting('templateMetaclass'): if self.setting('templateMetaclass'):
self._generatedAttribs.append( self._generatedAttribs.append(
'__metaclass__ = '+self.setting('templateMetaclass')) '__metaclass__ = ' + self.setting('templateMetaclass'))
self._initMethChunks = [] self._initMethChunks = []
self._blockMetaData = {} self._blockMetaData = {}
self._errorCatcherCount = 0 self._errorCatcherCount = 0
self._placeholderToErrorCatcherMap = {} self._placeholderToErrorCatcherMap = {}
def cleanupState(self): def cleanupState(self):
while self._activeMethodsList: while self._activeMethodsList:
methCompiler = self._popActiveMethodCompiler() methCompiler = self._popActiveMethodCompiler()
self._swallowMethodCompiler(methCompiler) self._swallowMethodCompiler(methCompiler)
self._setupInitMethod() self._setupInitMethod()
if self._mainMethodName == 'respond': if self._mainMethodName == 'respond':
if self.setting('setup__str__method'): if self.setting('setup__str__method'):
self._generatedAttribs.append( self._generatedAttribs.append(
'def __str__(self): return self.respond()') 'def __str__(self): return self.respond()')
self.addAttribute('_mainCheetahMethod_for_' + self._className + self.addAttribute(
' = ' + repr(self._mainMethodName)) '_mainCheetahMethod_for_' + self._className
+ ' = ' + repr(self._mainMethodName))
def _setupInitMethod(self): def _setupInitMethod(self):
__init__ = self._spawnMethodCompiler( __init__ = self._spawnMethodCompiler(
'__init__', klass=self.methodCompilerClassForInit) '__init__', klass=self.methodCompilerClassForInit)
__init__.setMethodSignature("def __init__(self, *args, **KWs)") __init__.setMethodSignature("def __init__(self, *args, **KWs)")
__init__.addChunk( __init__.addChunk(
'super(%s, self).__init__(*args, **KWs)' % self._className) 'super(%s, self).__init__(*args, **KWs)' % self._className)
__init__.addChunk( __init__.addChunk(
_initMethod_initCheetah % {'className': self._className}) _initMethod_initCheetah % {'className': self._className})
for chunk in self._initMethChunks: for chunk in self._initMethChunks:
skipping to change at line 1327 skipping to change at line 1327
self._swallowMethodCompiler(__init__, pos=0) self._swallowMethodCompiler(__init__, pos=0)
def _addSourceFileMonitoring(self, fileName): def _addSourceFileMonitoring(self, fileName):
# @@TR: this stuff needs auditing for Cheetah 2.0 # @@TR: this stuff needs auditing for Cheetah 2.0
# the first bit is added to init # the first bit is added to init
self.addChunkToInit('self._filePath = ' + repr(fileName)) self.addChunkToInit('self._filePath = ' + repr(fileName))
self.addChunkToInit('self._fileMtime = ' + str(getmtime(fileName))) self.addChunkToInit('self._fileMtime = ' + str(getmtime(fileName)))
# the rest is added to the main output method of the class # the rest is added to the main output method of the class
# ('mainMethod') # ('mainMethod')
self.addChunk('if exists(self._filePath) and ' + self.addChunk(
'getmtime(self._filePath) > self._fileMtime:') 'if exists(self._filePath) and '
+ 'getmtime(self._filePath) > self._fileMtime:')
self.indent() self.indent()
self.addChunk( self.addChunk(
'self._compile(file=self._filePath, moduleName=' 'self._compile(file=self._filePath, moduleName='
+ self._className + ')') + self._className + ')')
self.addChunk( self.addChunk(
'write(getattr(self, self._mainCheetahMethod_for_' 'write(getattr(self, self._mainCheetahMethod_for_'
+ self._className + ')(trans=trans))') + self._className + ')(trans=trans))')
self.addStop() self.addStop()
self.dedent() self.dedent()
skipping to change at line 1432 skipping to change at line 1433
self._classDocStringLines.append(line.replace('%', '%%')) self._classDocStringLines.append(line.replace('%', '%%'))
def addChunkToInit(self, chunk): def addChunkToInit(self, chunk):
self._initMethChunks.append(chunk) self._initMethChunks.append(chunk)
def addAttribute(self, attribExpr): def addAttribute(self, attribExpr):
# First test to make sure that the user hasn't used # First test to make sure that the user hasn't used
# any fancy Cheetah syntax (placeholders, directives, etc.) # any fancy Cheetah syntax (placeholders, directives, etc.)
# inside the expression # inside the expression
if attribExpr.find('VFN(') != -1 or attribExpr.find('VFFSL(') != -1: if attribExpr.find('VFN(') != -1 or attribExpr.find('VFFSL(') != -1:
raise ParseError(self, raise ParseError(
'Invalid #attr directive.' + self,
' It should only contain simple Python literals.') 'Invalid #attr directive. It should only contain '
+ 'simple Python literals.')
# now add the attribute # now add the attribute
self._generatedAttribs.append(attribExpr) self._generatedAttribs.append(attribExpr)
def addSuper(self, argsList, parserComment=None): def addSuper(self, argsList, parserComment=None):
className = self._className # self._baseClass className = self._className # self._baseClass
methodName = self._getActiveMethodCompiler().methodName() methodName = self._getActiveMethodCompiler().methodName()
argStringChunks = [] argStringChunks = []
for arg in argsList: for arg in argsList:
chunk = arg[0] chunk = arg[0]
skipping to change at line 1469 skipping to change at line 1471
'plus at line %s, col %s' % lineCol) 'plus at line %s, col %s' % lineCol)
return methodName return methodName
self._errorCatcherCount += 1 self._errorCatcherCount += 1
methodName = '__errorCatcher' + str(self._errorCatcherCount) methodName = '__errorCatcher' + str(self._errorCatcherCount)
self._placeholderToErrorCatcherMap[rawCode] = methodName self._placeholderToErrorCatcherMap[rawCode] = methodName
catcherMeth = self._spawnMethodCompiler( catcherMeth = self._spawnMethodCompiler(
methodName, methodName,
klass=MethodCompiler, klass=MethodCompiler,
initialMethodComment=('## CHEETAH: Generated from ' + rawCode + initialMethodComment=(
' at line %s, col %s' % lineCol + '.') '## CHEETAH: Generated from ' + rawCode
) + ' at line %s, col %s' % lineCol + '.')
)
catcherMeth.setMethodSignature( catcherMeth.setMethodSignature(
'def ' + methodName + 'def ' + methodName
'(self, localsDict={})') # is this use of localsDict right? + '(self, localsDict={})') # is this use of localsDict right?
catcherMeth.addChunk('try:') catcherMeth.addChunk('try:')
catcherMeth.indent() catcherMeth.indent()
catcherMeth.addChunk("return eval('''" + codeChunk + catcherMeth.addChunk(
"''', globals(), localsDict)") "return eval('''" + codeChunk + "''', globals(), localsDict)")
catcherMeth.dedent() catcherMeth.dedent()
catcherMeth.addChunk( catcherMeth.addChunk(
'except self._CHEETAH__errorCatcher.exceptions() as e:') 'except self._CHEETAH__errorCatcher.exceptions() as e:')
catcherMeth.indent() catcherMeth.indent()
catcherMeth.addChunk( catcherMeth.addChunk(
"return self._CHEETAH__errorCatcher.warn(exc_val=e, code= " + "return self._CHEETAH__errorCatcher.warn(exc_val=e, code= "
repr(codeChunk) + " , rawCode= " + + repr(codeChunk) + " , rawCode= "
repr(rawCode) + " , lineCol=" + str(lineCol) + ")") + repr(rawCode) + " , lineCol=" + str(lineCol) + ")")
catcherMeth.cleanupState() catcherMeth.cleanupState()
self._swallowMethodCompiler(catcherMeth) self._swallowMethodCompiler(catcherMeth)
return methodName return methodName
def closeDef(self): def closeDef(self):
self.commitStrConst() self.commitStrConst()
methCompiler = self._popActiveMethodCompiler() methCompiler = self._popActiveMethodCompiler()
self._swallowMethodCompiler(methCompiler) self._swallowMethodCompiler(methCompiler)
skipping to change at line 1538 skipping to change at line 1541
__unicode__ = classDef __unicode__ = classDef
def wrapClassDef(self): def wrapClassDef(self):
ind = self.setting('indentationStep') ind = self.setting('indentationStep')
classDefChunks = [self.classSignature(), classDefChunks = [self.classSignature(),
self.classDocstring(), self.classDocstring(),
] ]
def addMethods(): def addMethods():
classDefChunks.extend([ classDefChunks.extend([
ind + '#'*50, ind + '#'*50, # noqa: E226 missing whitespace around operator
ind + '## CHEETAH GENERATED METHODS', ind + '## CHEETAH GENERATED METHODS',
'\n', '\n',
self.methodDefs(), self.methodDefs(),
]) ])
def addAttributes(): def addAttributes():
classDefChunks.extend([ classDefChunks.extend([
ind + '#'*50, ind + '#'*50, # noqa: E226 missing whitespace around operator
ind + '## CHEETAH GENERATED ATTRIBUTES', ind + '## CHEETAH GENERATED ATTRIBUTES',
'\n', '\n',
self.attributes(), self.attributes(),
]) ])
if self.setting('outputMethodsBeforeAttributes'): if self.setting('outputMethodsBeforeAttributes'):
addMethods() addMethods()
addAttributes() addAttributes()
else: else:
addAttributes() addAttributes()
addMethods() addMethods()
classDef = '\n'.join(classDefChunks) classDef = '\n'.join(classDefChunks)
self._classDef = classDef self._classDef = classDef
return classDef return classDef
def classSignature(self): def classSignature(self):
return "class %s(%s):" % (self.className(), self._baseClass) return "class %s(%s):" % (self.className(), self._baseClass)
def classDocstring(self): def classDocstring(self):
if not self._classDocStringLines: if not self._classDocStringLines:
return '' return ''
ind = self.setting('indentationStep') ind = self.setting('indentationStep')
docStr = ('%(ind)s"""\n%(ind)s' + docStr = ('%(ind)s"""\n%(ind)s'
'\n%(ind)s'.join(self._classDocStringLines) + + '\n%(ind)s'.join(self._classDocStringLines)
'\n%(ind)s"""\n' + '\n%(ind)s"""\n'
) % {'ind': ind} ) % {'ind': ind}
return docStr return docStr
def methodDefs(self): def methodDefs(self):
methodDefs = [ methodDefs = [
methGen.methodDef() for methGen in self._finishedMethods()] methGen.methodDef() for methGen in self._finishedMethods()]
return '\n\n'.join(methodDefs) return '\n\n'.join(methodDefs)
def attributes(self): def attributes(self):
try: try:
skipping to change at line 1762 skipping to change at line 1765
"from Cheetah.Version import MinCompatibleVersionTuple " "from Cheetah.Version import MinCompatibleVersionTuple "
"as RequiredCheetahVersionTuple", "as RequiredCheetahVersionTuple",
"from Cheetah.Template import Template", "from Cheetah.Template import Template",
"from Cheetah.DummyTransaction import *", "from Cheetah.DummyTransaction import *",
"from Cheetah.NameMapper import NotFound, " "from Cheetah.NameMapper import NotFound, "
"valueForName, valueFromSearchList, valueFromFrameOrSearchList", "valueForName, valueFromSearchList, valueFromFrameOrSearchList",
"from Cheetah.CacheRegion import CacheRegion", "from Cheetah.CacheRegion import CacheRegion",
"import Cheetah.Filters as Filters", "import Cheetah.Filters as Filters",
"import Cheetah.ErrorCatchers as ErrorCatchers", "import Cheetah.ErrorCatchers as ErrorCatchers",
"from Cheetah.compat import unicode", "from Cheetah.compat import unicode",
] ]
self._importedVarNames = ['sys', self._importedVarNames = ['sys',
'os', 'os',
'os.path', 'os.path',
'time', 'time',
'types', 'types',
'Template', 'Template',
'DummyTransaction', 'DummyTransaction',
'NotFound', 'NotFound',
'Filters', 'Filters',
'ErrorCatchers', 'ErrorCatchers',
'CacheRegion', 'CacheRegion',
] ]
self._moduleConstants = [ self._moduleConstants = [
"VFFSL=valueFromFrameOrSearchList", "VFFSL=valueFromFrameOrSearchList",
"VFSL=valueFromSearchList", "VFSL=valueFromSearchList",
"VFN=valueForName", "VFN=valueForName",
"currentTime=time.time", "currentTime=time.time",
] ]
def compile(self): def compile(self):
classCompiler = self._spawnClassCompiler(self._mainClassName) classCompiler = self._spawnClassCompiler(self._mainClassName)
if self._baseclassName: if self._baseclassName:
classCompiler.setBaseClass(self._baseclassName) classCompiler.setBaseClass(self._baseclassName)
self._addActiveClassCompiler(classCompiler) self._addActiveClassCompiler(classCompiler)
self._parser.parse() self._parser.parse()
self._swallowClassCompiler(self._popActiveClassCompiler()) self._swallowClassCompiler(self._popActiveClassCompiler())
self._compiled = True self._compiled = True
self._parser.cleanup() self._parser.cleanup()
skipping to change at line 1884 skipping to change at line 1887
importStatement = "from %s import %s" % ( importStatement = "from %s import %s" % (
modName, klass) modName, klass)
self.addImportStatement(importStatement) self.addImportStatement(importStatement)
self.addImportedVarNames((klass,)) self.addImportedVarNames((klass,))
else: else:
needToAddImport = True needToAddImport = True
modName = chunks[0] modName = chunks[0]
for chunk in chunks[1:-1]: for chunk in chunks[1:-1]:
if modName in self.importedVarNames(): if modName in self.importedVarNames():
needToAddImport = False needToAddImport = False
finalBaseClassName = klass.replace(modName+'.', '') finalBaseClassName = klass.replace(modName + '.',
'')
baseclasses.append(finalBaseClassName) baseclasses.append(finalBaseClassName)
break break
else: else:
modName += '.'+chunk modName += '.' + chunk
if needToAddImport: if needToAddImport:
modName, finalClassName = ( modName, finalClassName = (
'.'.join(chunks[:-1]), chunks[-1]) '.'.join(chunks[:-1]), chunks[-1])
# if finalClassName != chunks[:-1][-1]: # if finalClassName != chunks[:-1][-1]:
if finalClassName != chunks[-2]: if finalClassName != chunks[-2]:
# we assume the class name to be the module name # we assume the class name to be the module name
modName = '.'.join(chunks) modName = '.'.join(chunks)
baseclasses.append(finalClassName) baseclasses.append(finalClassName)
importStatement = "from %s import %s" % ( importStatement = "from %s import %s" % (
modName, finalClassName) modName, finalClassName)
skipping to change at line 1955 skipping to change at line 1959
def addModuleGlobal(self, line): def addModuleGlobal(self, line):
"""Adds a line of global module code. It is inserted after the import """Adds a line of global module code. It is inserted after the import
statements and Cheetah default module constants. statements and Cheetah default module constants.
""" """
self._moduleConstants.append(line) self._moduleConstants.append(line)
def addSpecialVar(self, basename, contents, includeUnderscores=True): def addSpecialVar(self, basename, contents, includeUnderscores=True):
"""Adds module __specialConstant__ to the module globals. """Adds module __specialConstant__ to the module globals.
""" """
name = includeUnderscores and '__'+basename+'__' or basename name = includeUnderscores and '__' + basename + '__' or basename
self._specialVars[name] = contents.strip() self._specialVars[name] = contents.strip()
def addImportStatement(self, impStatement): def addImportStatement(self, impStatement):
settings = self.settings() settings = self.settings()
if not self._methodBodyChunks or settings.get('useLegacyImportMode'): if not self._methodBodyChunks or settings.get('useLegacyImportMode'):
# In the case where we are importing inline # In the case where we are importing inline
# in the middle of a source block # in the middle of a source block
# we don't want to inadvertantly import the module # we don't want to inadvertantly import the module
# at the top of the file either # at the top of the file either
self._importStatements.append(impStatement) self._importStatements.append(impStatement)
skipping to change at line 2020 skipping to change at line 2024
# methods for module code wrapping # methods for module code wrapping
def getModuleCode(self): def getModuleCode(self):
if not self._compiled: if not self._compiled:
self.compile() self.compile()
if self._moduleDef: if self._moduleDef:
return self._moduleDef return self._moduleDef
else: else:
return self.wrapModuleDef() return self.wrapModuleDef()
__str__ = getModuleCode def __to_bytes(self):
code = self.getModuleCode()
if isinstance(code, bytes):
return code
return code.encode(self.getModuleEncoding())
def __to_unicode(self):
code = self.getModuleCode()
if isinstance(code, bytes):
return code.decode(self.getModuleEncoding())
return code
if PY2:
__str__ = __to_bytes
__unicode__ = __to_unicode
else:
__bytes__ = __to_bytes
__str__ = __to_unicode
def wrapModuleDef(self): def wrapModuleDef(self):
self.addSpecialVar('CHEETAH_docstring', self.setting('defDocStrMsg')) self.addSpecialVar('CHEETAH_docstring', self.setting('defDocStrMsg'))
self.addModuleGlobal('__CHEETAH_version__ = %r' % Version) self.addModuleGlobal('__CHEETAH_version__ = %r' % Version)
self.addModuleGlobal('__CHEETAH_versionTuple__ = %r' % (VersionTuple,)) self.addModuleGlobal('__CHEETAH_versionTuple__ = %r' % (VersionTuple,))
if self.setting('addTimestampsToCompilerOutput'): if self.setting('addTimestampsToCompilerOutput'):
self.addModuleGlobal('__CHEETAH_genTime__ = %r' % time.time()) self.addModuleGlobal('__CHEETAH_genTime__ = %r' % time.time())
self.addModuleGlobal( self.addModuleGlobal(
'__CHEETAH_genTimestamp__ = %r' % self.timestamp()) '__CHEETAH_genTimestamp__ = %r' % self.timestamp())
if self._filePath: if self._filePath:
skipping to change at line 2080 skipping to change at line 2101
%(footer)s %(footer)s
""" % { """ % {
'header': self.moduleHeader(), 'header': self.moduleHeader(),
'docstring': self.moduleDocstring(), 'docstring': self.moduleDocstring(),
'specialVars': self.specialVars(), 'specialVars': self.specialVars(),
'imports': self.importStatements(), 'imports': self.importStatements(),
'constants': self.moduleConstants(), 'constants': self.moduleConstants(),
'classes': self.classDefs(), 'classes': self.classDefs(),
'footer': self.moduleFooter(), 'footer': self.moduleFooter(),
'mainClassName': self._mainClassName, 'mainClassName': self._mainClassName,
} } # noqa
self._moduleDef = moduleDef self._moduleDef = moduleDef
return moduleDef return moduleDef
def timestamp(self, theTime=None): def timestamp(self, theTime=None):
if not theTime: if not theTime:
theTime = time.time() theTime = time.time()
return time.asctime(time.localtime(theTime)) return time.asctime(time.localtime(theTime))
def moduleHeader(self): def moduleHeader(self):
header = self._moduleShBang + '\n' header = self._moduleShBang + '\n'
header += self._moduleEncodingStr + '\n' header += self._moduleEncodingStr + '\n'
if self._moduleHeaderLines: if self._moduleHeaderLines:
offSet = self.setting('commentOffset') offSet = self.setting('commentOffset')
header += ( header += (
'#' + ' '*offSet + '#' + ' '*offSet # noqa: E226,E501 missing whitespace around op
('\n#' + ' '*offSet).join(self._moduleHeaderLines) + '\n') erator
+ ('\n#' + ' '*offSet).join(self._moduleHeaderLines) # noqa: E2
26,E501 missing whitespace around operator
+ '\n')
return header return header
def moduleDocstring(self): def moduleDocstring(self):
if not self._moduleDocStringLines: if not self._moduleDocStringLines:
return '' return ''
return ('"""' + return ('"""' + '\n'.join(self._moduleDocStringLines)
'\n'.join(self._moduleDocStringLines) + + '\n"""\n')
'\n"""\n')
def specialVars(self): def specialVars(self):
chunks = [] chunks = []
theVars = self._specialVars theVars = self._specialVars
keys = sorted(theVars.keys()) keys = sorted(theVars.keys())
for key in keys: for key in keys:
chunks.append(key + ' = ' + repr(theVars[key])) chunks.append(key + ' = ' + repr(theVars[key]))
return '\n'.join(chunks) return '\n'.join(chunks)
def importStatements(self): def importStatements(self):
 End of changes. 47 change blocks. 
78 lines changed or deleted 102 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)