[Checkins] SVN: z3c.pt/trunk/ Use dynamic expression evaluation framework that comes with Chameleon. Note that this requires Chameleon 2.2 or greater.

Malthe Borch mborch at gmail.com
Thu Jul 28 15:13:40 EDT 2011


Log message for revision 122399:
  Use dynamic expression evaluation framework that comes with Chameleon. Note that this requires Chameleon 2.2 or greater.

Changed:
  U   z3c.pt/trunk/CHANGES.txt
  U   z3c.pt/trunk/setup.py
  U   z3c.pt/trunk/src/z3c/pt/expressions.py
  U   z3c.pt/trunk/src/z3c/pt/pagetemplate.py

-=-
Modified: z3c.pt/trunk/CHANGES.txt
===================================================================
--- z3c.pt/trunk/CHANGES.txt	2011-07-28 15:57:38 UTC (rev 122398)
+++ z3c.pt/trunk/CHANGES.txt	2011-07-28 19:13:39 UTC (rev 122399)
@@ -1,6 +1,11 @@
 Changelog
 =========
 
+In next release ...
+
+- Use dynamic expression evaluation framework that comes included with
+  Chameleon.
+
 2.0 (2011-07-14)
 ~~~~~~~~~~~~~~~~
 

Modified: z3c.pt/trunk/setup.py
===================================================================
--- z3c.pt/trunk/setup.py	2011-07-28 15:57:38 UTC (rev 122398)
+++ z3c.pt/trunk/setup.py	2011-07-28 19:13:39 UTC (rev 122399)
@@ -1,7 +1,7 @@
 from setuptools import setup, find_packages
 import sys
 
-version = '2.0'
+version = '2.1dev'
 
 install_requires = [
     'setuptools',
@@ -10,7 +10,7 @@
     'zope.i18n >= 3.5',
     'zope.traversing',
     'zope.contentprovider',
-    'Chameleon >= 2.0',
+    'Chameleon >= 2.2',
     ]
 
 setup(name='z3c.pt',

Modified: z3c.pt/trunk/src/z3c/pt/expressions.py
===================================================================
--- z3c.pt/trunk/src/z3c/pt/expressions.py	2011-07-28 15:57:38 UTC (rev 122398)
+++ z3c.pt/trunk/src/z3c/pt/expressions.py	2011-07-28 19:13:39 UTC (rev 122399)
@@ -22,6 +22,7 @@
 from chameleon.astutil import load
 from chameleon.astutil import Symbol
 from chameleon.astutil import Static
+from chameleon.astutil import NameLookupRewriteVisitor
 from chameleon.exc import ExpressionError
 
 _marker = object()
@@ -216,8 +217,20 @@
 
 
 class PythonExpr(BasePythonExpr):
+    builtins = {
+        'path': template("tales(econtext, rcontext, 'path')", mode="eval"),
+        'exists': template("tales(econtext, rcontext, 'exists')", mode="eval"),
+        }
+
     def __init__(self, expression):
         self.expression = expression
 
     def __call__(self, target, engine):
         return self.translate(self.expression, target)
+
+    def rewrite(self, node):
+        return self.builtins.get(node.id, node)
+
+    @property
+    def transform(self):
+        return NameLookupRewriteVisitor(self.rewrite)

Modified: z3c.pt/trunk/src/z3c/pt/pagetemplate.py
===================================================================
--- z3c.pt/trunk/src/z3c/pt/pagetemplate.py	2011-07-28 15:57:38 UTC (rev 122398)
+++ z3c.pt/trunk/src/z3c/pt/pagetemplate.py	2011-07-28 19:13:39 UTC (rev 122399)
@@ -7,9 +7,7 @@
 from chameleon.zpt import template
 from chameleon.tales import StringExpr
 from chameleon.tales import NotExpr
-from chameleon.nodes import Assignment
-from chameleon.nodes import Program
-from chameleon.compiler import Compiler
+from chameleon.compiler import ExpressionEvaluator
 
 from z3c.pt import expressions
 
@@ -20,7 +18,6 @@
     MV = object()
 
 _marker = object()
-_expr_cache = {}
 
 
 class OpaqueDict(dict):
@@ -69,6 +66,18 @@
 
     default_expression = "path"
 
+    @property
+    def builtins(self):
+        builtins = {
+            'nothing': None,
+            'modules': sys_modules,
+            }
+
+        tales = ExpressionEvaluator(self.engine, builtins)
+        builtins['tales'] = tales
+
+        return builtins
+
     def bind(self, ob, request=None):
         def render(request=request, **kwargs):
             context = self._pt_get_context(ob, request, kwargs)
@@ -91,8 +100,6 @@
                     target_language = None
 
         context['target_language'] = target_language
-        context['path'] = self.evaluate_path
-        context['exists'] = self.evaluate_exists
 
         # bind translation-method to request
         def translate(
@@ -117,7 +124,6 @@
         base_renderer = super(BaseTemplate, self).render
         return base_renderer(**context)
 
-
     def __call__(self, *args, **kwargs):
         bound_pt = self.bind(self)
         return bound_pt(*args, **kwargs)
@@ -128,51 +134,10 @@
             here=instance,
             options=kwargs,
             request=request,
-            nothing=None,
-            modules=sys_modules
+            template=self,
             )
 
-    def evaluate_expression(self, pragma, expr):
-        key = "%s(%s)" % (pragma, expr)
 
-        try:
-            function = _expr_cache[key]
-        except KeyError:
-            expression = "%s:%s" % (pragma, expr)
-            assignment = Assignment(["_expr_result"], expression, True)
-            macro = Program(None, [assignment])
-            compiler = Compiler(self.engine, macro)
-
-            d = {}
-            exec compiler.code in d
-            function = _expr_cache[key] = d['render']
-
-        # acquire template locals and update with symbol mapping
-        frame = sys._getframe()
-        while True:
-            l = frame.f_locals
-            econtext = l.get('econtext')
-            if econtext is not None:
-                break
-
-            frame = frame.f_back
-            if frame is None:
-                raise RuntimeError("Can't locate template frame.")
-
-        rcontext = l.get('rcontext')
-        function([], econtext, rcontext)
-        return econtext['_expr_result']
-
-    def evaluate_path(self, expr):
-        return self.evaluate_expression('path', expr)
-
-    def evaluate_exists(self, expr):
-        try:
-            return self.evaluate_expression('exists', expr)
-        except NameError:
-            return False
-
-
 class BaseTemplateFile(BaseTemplate, template.PageTemplateFile):
     """If ``filename`` is a relative path, the module path of the
     class where the instance is used to get an absolute path."""
@@ -258,8 +223,7 @@
             context=context,
             request=request,
             options=kwargs,
-            nothing=None,
-            modules=sys_modules
+            template=self,
             )
 
     def __call__(self, _ob=None, context=None, request=None, **kwargs):



More information about the checkins mailing list