public
Last active

  • Download Gist
gistfile1.diff
Diff
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
commit ece695c5b24e728cf3a9a9eb62a1f61c90a5b31c
Author: R. Tyler Ballance <tyler@slide.com>
Date: Sat Apr 18 17:21:41 2009 -0700
 
Add support for specifying @staticmethod and @classmethod decorators on template methods
The classmethod and staticmethod keyword arguments will become the searchList as far as the
method body is concerned
Signed-off-by: R. Tyler Ballance <tyler@slide.com>
 
diff --git a/src/Compiler.py b/src/Compiler.py
index 7cae1c5..8f1ea41 100644
--- a/src/Compiler.py
+++ b/src/Compiler.py
@@ -812,7 +812,8 @@ class MethodCompiler(GenUtils):
return self.nextCacheID()
def startCallRegion(self, functionName, args, lineCol, regionTitle='CALL'):
- class CallDetails: pass
+ class CallDetails(object):
+ pass
callDetails = CallDetails()
callDetails.ID = ID = self.nextCallRegionID()
callDetails.functionName = functionName
@@ -982,6 +983,8 @@ class AutoMethodCompiler(MethodCompiler):
MethodCompiler._setupState(self)
self._argStringList = [ ("self",None) ]
self._streamingEnabled = True
+ self._isClassMethod = None
+ self._isStaticMethod = None
def _useKWsDictArgForPassingTrans(self):
alreadyHasTransArg = [argname for argname,defval in self._argStringList
@@ -989,6 +992,16 @@ class AutoMethodCompiler(MethodCompiler):
return (self.methodName()!='respond'
and not alreadyHasTransArg
and self.setting('useKWsDictArgForPassingTrans'))
+
+ def isClassMethod(self):
+ if self._isClassMethod is None:
+ self._isClassMethod = '@classmethod' in self._decorators
+ return self._isClassMethod
+
+ def isStaticMethod(self):
+ if self._isStaticMethod is None:
+ self._isStaticMethod = '@staticmethod' in self._decorators
+ return self._isStaticMethod
def cleanupState(self):
MethodCompiler.cleanupState(self)
@@ -1030,7 +1043,7 @@ class AutoMethodCompiler(MethodCompiler):
if self._initialMethodComment:
self.addChunk(self._initialMethodComment)
- if self._streamingEnabled:
+ if self._streamingEnabled and not self.isClassMethod() and not self.isStaticMethod():
if self._useKWsDictArgForPassingTrans() and self._kwargsName:
self.addChunk('trans = %s.get("trans")'%self._kwargsName)
self.addChunk('if (not trans and not self._CHEETAH__isBuffering'
@@ -1058,9 +1071,11 @@ class AutoMethodCompiler(MethodCompiler):
pass
elif allowSearchListAsMethArg and 'searchList' in argNames:
self.addChunk('SL = searchList')
- else:
+ elif not self.isClassMethod() and not self.isStaticMethod():
self.addChunk('SL = self._CHEETAH__searchList')
- if self.setting('useFilters'):
+ else:
+ self.addChunk('SL = [KWS]')
+ if self.setting('useFilters') and not self.isClassMethod() and not self.isStaticMethod():
self.addChunk('_filter = self._CHEETAH__currentFilter')
self.addChunk('')
self.addChunk("#" *40)
@@ -1087,6 +1102,11 @@ class AutoMethodCompiler(MethodCompiler):
argStringChunks = []
for arg in self._argStringList:
chunk = arg[0]
+ if chunk == 'self' and self.isClassMethod():
+ chunk = 'cls'
+ if chunk == 'self' and self.isStaticMethod():
+ # Skip the "self" method for @staticmethod decorators
+ continue
if not arg[1] == None:
chunk += '=' + arg[1]
argStringChunks.append(chunk)
diff --git a/src/Tests/Template.py b/src/Tests/Template.py
index bca1b30..53e3a99 100644
--- a/src/Tests/Template.py
+++ b/src/Tests/Template.py
@@ -322,6 +322,36 @@ class TryExceptImportTest(TemplateTest):
klass = Template.compile(source=source, compilerSettings={'useLegacyImportMode' : False})
t = klass(namespaces={'foo' : 1234})
+class ClassMethodSupport(TemplateTest):
+ def test_BasicDecorator(self):
+ template = '''
+ #@classmethod
+ #def myClassMethod()
+ #return '$foo = %s' % $foo
+ #end def
+ '''
+ template = Template.compile(source=template)
+ try:
+ rc = template.myClassMethod(foo='bar')
+ assert rc == '$foo = bar', (rc, 'Template class method didn\'t return what I expected')
+ except AttributeError, ex:
+ self.fail(ex)
+
+class StaticMethodSupport(TemplateTest):
+ def test_BasicDecorator(self):
+ template = '''
+ #@staticmethod
+ #def myStaticMethod()
+ #return '$foo = %s' % $foo
+ #end def
+ '''
+ template = Template.compile(source=template)
+ try:
+ rc = template.myStaticMethod(foo='bar')
+ assert rc == '$foo = bar', (rc, 'Template class method didn\'t return what I expected')
+ except AttributeError, ex:
+ self.fail(ex)
+

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.