diff options
Diffstat (limited to 'cheetah/Compiler.py')
-rw-r--r-- | cheetah/Compiler.py | 142 |
1 files changed, 64 insertions, 78 deletions
diff --git a/cheetah/Compiler.py b/cheetah/Compiler.py index 39c7f51..8946710 100644 --- a/cheetah/Compiler.py +++ b/cheetah/Compiler.py @@ -25,8 +25,8 @@ from Cheetah.Utils.Indenter import indentize # an undocumented preprocessor from Cheetah import ErrorCatchers from Cheetah import NameMapper from Cheetah.Parser import Parser, ParseError, specialVarRE, \ - STATIC_CACHE, REFRESH_CACHE, SET_LOCAL, SET_GLOBAL,SET_MODULE, \ - unicodeDirectiveRE, encodingDirectiveRE,escapedNewlineRE + STATIC_CACHE, REFRESH_CACHE, SET_LOCAL, SET_GLOBAL, SET_MODULE, \ + unicodeDirectiveRE, encodingDirectiveRE, escapedNewlineRE from Cheetah.NameMapper import NotFound, valueForName, valueFromSearchList, valueFromFrameOrSearchList VFFSL=valueFromFrameOrSearchList @@ -56,8 +56,8 @@ _DEFAULT_COMPILER_SETTINGS = [ ('commentOffset', 1, ''), ('outputRowColComments', True, ''), ('includeBlockMarkers', False, 'Wrap #block\'s in a comment in the template\'s output'), - ('blockMarkerStart', ('\n<!-- START BLOCK: ',' -->\n'), ''), - ('blockMarkerEnd', ('\n<!-- END BLOCK: ',' -->\n'), ''), + ('blockMarkerStart', ('\n<!-- START BLOCK: ', ' -->\n'), ''), + ('blockMarkerEnd', ('\n<!-- END BLOCK: ', ' -->\n'), ''), ('defDocStrMsg', 'Autogenerated by Cheetah: The Python-Powered Template Engine', ''), ('setup__str__method', False, ''), ('mainMethodName', 'respond', ''), @@ -379,13 +379,13 @@ class MethodCompiler(GenUtils): ind = self._indent*2 docStr = (ind + '"""\n' + ind + - ('\n' + ind).join([ln.replace('"""',"'''") for ln in self._docStringLines]) + + ('\n' + ind).join([ln.replace('"""', "'''") for ln in self._docStringLines]) + '\n' + ind + '"""\n') return docStr ## methods for adding code def addMethDocString(self, line): - self._docStringLines.append(line.replace('%','%%')) + self._docStringLines.append(line.replace('%', '%%')) def addChunk(self, chunk): self.commitStrConst() @@ -418,7 +418,7 @@ class MethodCompiler(GenUtils): self.addChunk("if _v is not None: write(str(_v))") else: if self.setting('useFilters'): - self.addChunk("write(_filter(%s%s))"%(chunk,filterArgs)) + self.addChunk("write(_filter(%s%s))"%(chunk, filterArgs)) else: self.addChunk("write(str(%s))"%chunk) @@ -428,48 +428,35 @@ class MethodCompiler(GenUtils): 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 not strConst: - return - else: - reprstr = repr(strConst).replace('\\012','\n') - i = 0 - out = [] - if reprstr.startswith('u'): - i = 1 - out = ['u'] - body = escapedNewlineRE.sub('\n', reprstr[i+1:-1]) - - if reprstr[i]=="'": - out.append("'''") - out.append(body) - out.append("'''") - else: - out.append('"""') - out.append(body) - out.append('"""') - self.addWriteChunk(''.join(out)) + if not self._pendingStrConstChunks: + return + + strConst = ''.join(self._pendingStrConstChunks) + self._pendingStrConstChunks = [] + if not strConst: + return + + reprstr = repr(strConst) + i = 0 + out = [] + if reprstr.startswith('u'): + i = 1 + out = ['u'] + body = escapedNewlineRE.sub('\\1\n', reprstr[i+1:-1]) + + if reprstr[i]=="'": + out.append("'''") + out.append(body) + out.append("'''") + else: + out.append('"""') + out.append(body) + out.append('"""') + self.addWriteChunk(''.join(out)) def handleWSBeforeDirective(self): """Truncate the pending strCont to the beginning of the current line. @@ -545,7 +532,7 @@ class MethodCompiler(GenUtils): splitPos2 = LVALUE.find('[') if splitPos1 > 0 and splitPos2==-1: splitPos = splitPos1 - elif splitPos1 > 0 and splitPos1 < max(splitPos2,0): + elif splitPos1 > 0 and splitPos1 < max(splitPos2, 0): splitPos = splitPos1 else: splitPos = splitPos2 @@ -579,7 +566,7 @@ class MethodCompiler(GenUtils): def addRepeat(self, expr, lineCol=None): #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), lineCol=lineCol) + self.addFor('for __i%s in range(%s)' % (self._repeatCount, expr), lineCol=lineCol) def addIndentingDirective(self, expr, lineCol=None): if expr and not expr[-1] == ':': @@ -623,7 +610,7 @@ class MethodCompiler(GenUtils): self.dedent() def addElse(self, expr, dedent=True, lineCol=None): - expr = re.sub(r'else[ \f\t]+if','elif', expr) + expr = re.sub(r'else[ \f\t]+if', 'elif', expr) self.addReIndentingDirective(expr, dedent=dedent, lineCol=lineCol) def addElif(self, expr, dedent=True, lineCol=None): @@ -660,7 +647,7 @@ class MethodCompiler(GenUtils): def addYield(self, expr): assert not self._hasReturnStatement self._isGenerator = True - if expr.replace('yield','').strip(): + if expr.replace('yield', '').strip(): self.addChunk(expr) else: self.addChunk('if _dummyTrans:') @@ -727,9 +714,9 @@ class MethodCompiler(GenUtils): # @@TR: we should add some runtime logging to this ID = self.nextCacheID() - interval = cacheInfo.get('interval',None) - test = cacheInfo.get('test',None) - customID = cacheInfo.get('id',None) + interval = cacheInfo.get('interval', None) + test = cacheInfo.get('test', None) + customID = cacheInfo.get('id', None) if customID: ID = customID varyBy = cacheInfo.get('varyBy', repr(ID)) @@ -896,7 +883,7 @@ class MethodCompiler(GenUtils): captureDetails.assignTo = assignTo captureDetails.lineCol = lineCol - self._captureRegionsStack.append((ID,captureDetails)) # attrib of current methodCompiler + self._captureRegionsStack.append((ID, captureDetails)) # attrib of current methodCompiler self.addChunk('## START CAPTURE REGION: '+ID +' '+assignTo +' at line %s, col %s'%lineCol + ' in the source.') @@ -982,13 +969,13 @@ class AutoMethodCompiler(MethodCompiler): def _setupState(self): MethodCompiler._setupState(self) - self._argStringList = [ ("self",None) ] + self._argStringList = [ ("self", None) ] self._streamingEnabled = True self._isClassMethod = None self._isStaticMethod = None def _useKWsDictArgForPassingTrans(self): - alreadyHasTransArg = [argname for argname,defval in self._argStringList + alreadyHasTransArg = [argname for argname, defval in self._argStringList if argname=='trans'] return (self.methodName()!='respond' and not alreadyHasTransArg @@ -1015,12 +1002,12 @@ class AutoMethodCompiler(MethodCompiler): if self._streamingEnabled: kwargsName = None positionalArgsListName = None - for argname,defval in self._argStringList: + for argname, defval in self._argStringList: if argname.strip().startswith('**'): - kwargsName = argname.strip().replace('**','') + kwargsName = argname.strip().replace('**', '') break elif argname.strip().startswith('*'): - positionalArgsListName = argname.strip().replace('*','') + positionalArgsListName = argname.strip().replace('*', '') if not kwargsName and self._useKWsDictArgForPassingTrans(): kwargsName = 'KWS' @@ -1100,7 +1087,7 @@ class AutoMethodCompiler(MethodCompiler): self.addChunk('return _dummyTrans and trans.response().getvalue() or ""') def addMethArg(self, name, defVal=None): - self._argStringList.append( (name,defVal) ) + self._argStringList.append( (name, defVal) ) def methodSignature(self): argStringChunks = [] @@ -1136,7 +1123,7 @@ if not self._CHEETAH__instanceInitialized: for k,v in KWs.items(): if k in allowedKWs: cheetahKWArgs[k] = v self._initCheetahInstance(**cheetahKWArgs) -""".replace('\n','\n'+' '*8) +""".replace('\n', '\n'+' '*8) class ClassCompiler(GenUtils): methodCompilerClass = AutoMethodCompiler @@ -1173,14 +1160,14 @@ class ClassCompiler(GenUtils): from the methods of this class!!! or you will be assigning to attributes of this object instead.""" - if self.__dict__.has_key(name): + if name in self.__dict__: 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 + raise AttributeError(name) def _setupState(self): self._classDef = None @@ -1333,9 +1320,9 @@ class ClassCompiler(GenUtils): self._decoratorsForNextMethod.append(decoratorExpr) def addClassDocString(self, line): - self._classDocStringLines.append( line.replace('%','%%')) + self._classDocStringLines.append( line.replace('%', '%%')) - def addChunkToInit(self,chunk): + def addChunkToInit(self, chunk): self._initMethChunks.append(chunk) def addAttribute(self, attribExpr): @@ -1364,7 +1351,7 @@ class ClassCompiler(GenUtils): 'super(%(className)s, self).%(methodName)s(%(argString)s)'%locals()) def addErrorCatcherCall(self, codeChunk, rawCode='', lineCol=''): - if self._placeholderToErrorCatcherMap.has_key(rawCode): + if rawCode in self._placeholderToErrorCatcherMap: methodName = self._placeholderToErrorCatcherMap[rawCode] if not self.setting('outputRowColComments'): self._methodsIndex[methodName].addMethDocString( @@ -1601,14 +1588,14 @@ class ModuleCompiler(SettingsManager, GenUtils): from the methods of this class!!! or you will be assigning to attributes of this object instead. """ - if self.__dict__.has_key(name): + if name in self.__dict__: 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 + raise AttributeError(name) def _initializeSettings(self): self.updateSettings(copy.deepcopy(DEFAULT_COMPILER_SETTINGS)) @@ -1848,7 +1835,7 @@ class ModuleCompiler(SettingsManager, GenUtils): self._getActiveClassCompiler().addAttribute(attribName + ' =' + expr) def addComment(self, comm): - if re.match(r'#+$',comm): # skip bar comments + if re.match(r'#+$', comm): # skip bar comments return specialVarMatch = specialVarRE.match(comm) @@ -1935,14 +1922,14 @@ if not hasattr(%(mainClassName)s, '_initCheetahAttributes'): templateAPIClass._addCheetahPlumbingCodeToClass(%(mainClassName)s) %(footer)s -""" % {'header':self.moduleHeader(), - 'docstring':self.moduleDocstring(), - 'specialVars':self.specialVars(), - 'imports':self.importStatements(), - 'constants':self.moduleConstants(), - 'classes':self.classDefs(), - 'footer':self.moduleFooter(), - 'mainClassName':self._mainClassName, +""" % {'header': self.moduleHeader(), + 'docstring': self.moduleDocstring(), + 'specialVars': self.specialVars(), + 'imports': self.importStatements(), + 'constants': self.moduleConstants(), + 'classes': self.classDefs(), + 'footer': self.moduleFooter(), + 'mainClassName': self._mainClassName, } self._moduleDef = moduleDef @@ -1976,8 +1963,7 @@ if not hasattr(%(mainClassName)s, '_initCheetahAttributes'): def specialVars(self): chunks = [] theVars = self._specialVars - keys = theVars.keys() - keys.sort() + keys = sorted(theVars.keys()) for key in keys: chunks.append(key + ' = ' + repr(theVars[key]) ) return '\n'.join(chunks) |