Created
April 30, 2009 21:46
-
-
Save rtyler/104709 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
+ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment