templater: keep a cache of Python functions for filter expressions
authorDirkjan Ochtman <dirkjan@ochtman.nl>
Sun, 17 May 2009 16:08:47 +0200
changeset 8476 d5dda64f5552
parent 8475 caaf1e779b37
child 8477 a0104303f400
templater: keep a cache of Python functions for filter expressions
mercurial/templater.py
--- a/mercurial/templater.py	Sun May 17 16:06:48 2009 +0200
+++ b/mercurial/templater.py	Sun May 17 16:08:47 2009 +0200
@@ -48,6 +48,7 @@
         self.loader = loader
         self.filters = filters
         self.defaults = defaults
+        self.cache = {}
 
     def process(self, t, map):
         '''Perform expansion. t is name of map element to expand. map contains
@@ -80,11 +81,17 @@
             yield self.process(format, lm)
 
     def _filter(self, expr, get, map):
-        parts = expr.split('|')
-        v = get(parts[0])
-        for f in parts[1:]:
-            v = self.filters[f](v)
-        return v
+        if expr not in self.cache:
+            parts = expr.split('|')
+            filters = parts[1:]
+            for f in filters:
+            	if f not in self.filters:
+                    raise SyntaxError(_("unknown filter '%s'") % expr)
+            calls = '('.join(i for i in reversed(filters))
+            end = ')' * len(filters)
+            code = "lambda _get: %s(_get('%s')%s" % (calls, parts[0], end)
+            self.cache[expr] = eval(code, self.filters)
+        return self.cache[expr](get)
 
     def _process(self, tmpl, map):
         '''Render a template. Returns a generator.'''