optimize filters on constant values
authorChristoph Hack <christoph@tux21b.org>
Tue, 8 Apr 2008 14:48:30 +0000 (16:48 +0200)
committerChristoph Hack <christoph@tux21b.org>
Tue, 8 Apr 2008 14:48:30 +0000 (16:48 +0200)
--HG--
branch : trunk

jinja2/compiler.py
jinja2/defaults.py
jinja2/filters.py
test.py

index 43cb439bfc5dd0665ed51f3ab163132459217070..a1e878323fa07e35c53a4076bd7ecf7ffcdd724a 100644 (file)
@@ -530,13 +530,22 @@ class CodeGenerator(NodeVisitor):
             self.visit(node.step, frame)
 
     def visit_Filter(self, node, frame):
-        for filter in node.filters:
+        value = node.node
+        flen = len(node.filters)
+        if isinstance(value, nodes.Const):
+            # try to optimize filters on constant values
+            for filter in reversed(node.filters):
+                value = nodes.Const(self.environment.filters \
+                    .get(filter.name)(self.environment, value.value))
+                print value
+                flen -= 1
+        for filter in node.filters[:flen]:
             if filter.name in frame.identifiers.declared_filter:
                 self.write('f_%s(' % filter.name)
             else:
                 self.write('context.filter[%r](' % filter.name)
-        self.visit(node.node, frame)
-        for filter in reversed(node.filters):
+        self.visit(value, frame)
+        for filter in reversed(node.filters[:flen]):
             self.signature(filter, frame)
             self.write(')')
 
index 37473ea8f895195e85525212648f9800c074b550..84c1b0842077d6f74ffa9a2e305dbbf9a2c5f601 100644 (file)
@@ -8,7 +8,7 @@
     :copyright: 2007 by Armin Ronacher.
     :license: BSD, see LICENSE for more details.
 """
-from jinja.filters import FILTERS as DEFAULT_FILTERS
+from jinja2.filters import FILTERS as DEFAULT_FILTERS
 from jinja.tests import TESTS as DEFAULT_TESTS
 DEFAULT_NAMESPACE = {}
 
index 6098b6ef87e43b985be6377459458d9e4080bb1d..45188226ec5cb1e96d95dd784a28bff12dcd0f7b 100644 (file)
@@ -15,6 +15,7 @@ try:
 except ImportError:
     itemgetter = lambda a: lambda b: b[a]
 from urllib import urlencode, quote
+from jinja.utils import escape
 
 
 _striptags_re = re.compile(r'(<!--.*?-->|<[^>]*>)')
@@ -94,18 +95,16 @@ def do_upper(s):
     Convert a value to uppercase.
     """
     return s.upper()
-do_upper = stringfilter(do_upper)
 
 
-def do_lower(s):
+def do_lower(env, s):
     """
     Convert a value to lowercase.
     """
     return s.lower()
-do_lower = stringfilter(do_lower)
 
 
-def do_escape(attribute=False):
+def do_escape(env, s, attribute=False):
     """
     XML escape ``&``, ``<``, and ``>`` in a string of data. If the
     optional parameter is `true` this filter will also convert
@@ -114,20 +113,12 @@ def do_escape(attribute=False):
 
     This method will have no effect it the value is already escaped.
     """
-    #: because filters are cached we can make a local alias to
-    #: speed things up a bit
-    e = escape
-    def wrapped(env, context, s):
-        if isinstance(s, TemplateData):
-            return s
-        elif hasattr(s, '__html__'):
-            return s.__html__()
-        #: small speedup, do not convert to unicode if we already
-        #: have an unicode object.
-        if s.__class__ is not unicode:
-            s = env.to_unicode(s)
-        return e(s, attribute)
-    return wrapped
+    # XXX: Does this still exists?
+    #if isinstance(s, TemplateData):
+    #    return s
+    if hasattr(s, '__html__'):
+        return s.__html__()
+    return escape(unicode(s), attribute)
 
 
 def do_xmlattr(autospace=False):
diff --git a/test.py b/test.py
index 68ed7b84e520af877280d7f4eae81d055fbc1323..186959ac76ab1e0f8412de64ac7bfeca02569047 100644 (file)
--- a/test.py
+++ b/test.py
@@ -4,13 +4,7 @@ from jinja2.compiler import generate
 
 env = Environment()
 ast = env.parse("""
-{% (a, b), c = foo() %}
-{% macro foo(a, b, c=42) %}
-  42 {{ arguments }}
-{% endmacro %}
-{% block body %}
-    {% bar = 23 %}
-{% endblock %}
+Hallo {{ name|e }}!, wie geht es {{ "<dir>"|e|lower }}?
 """)
 print ast
 print