[Checkins] SVN: z3c.pt/trunk/ Added dynamic scope support for dynamic path- and exists-methods (rarely used).
Malthe Borch
mborch at gmail.com
Wed Feb 18 08:18:54 EST 2009
Log message for revision 96695:
Added dynamic scope support for dynamic path- and exists-methods (rarely used).
Changed:
U z3c.pt/trunk/CHANGES.txt
U z3c.pt/trunk/src/z3c/pt/pagetemplate.py
-=-
Modified: z3c.pt/trunk/CHANGES.txt
===================================================================
--- z3c.pt/trunk/CHANGES.txt 2009-02-18 12:33:03 UTC (rev 96694)
+++ z3c.pt/trunk/CHANGES.txt 2009-02-18 13:18:54 UTC (rev 96695)
@@ -1,6 +1,10 @@
Changelog
---------
+- When evaluating path-expressions at runtime (e.g. the ``path``
+ method), run the source through the transform first to support
+ dynamic scope. [malthe]
+
Version 1.0b8 - February 17, 2009
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Modified: z3c.pt/trunk/src/z3c/pt/pagetemplate.py
===================================================================
--- z3c.pt/trunk/src/z3c/pt/pagetemplate.py 2009-02-18 12:33:03 UTC (rev 96694)
+++ z3c.pt/trunk/src/z3c/pt/pagetemplate.py 2009-02-18 13:18:54 UTC (rev 96695)
@@ -1,11 +1,13 @@
import os
import sys
+import compiler
from zope import i18n
from zope import component
from chameleon.core import types
from chameleon.core import config
+from chameleon.core import codegen
from chameleon.core import clauses
from chameleon.core import generation
@@ -19,10 +21,9 @@
def evaluate_expression(pragma, expr):
key = "%s(%s)" % (pragma, expr)
- cache = getattr(_expr_cache, key, _marker)
- if cache is not _marker:
- symbol_mapping, parts, source = cache
- else:
+ try:
+ symbol_mapping, parts, source = _expr_cache[key]
+ except KeyError:
translator = component.getUtility(IExpressionTranslator, name=pragma)
parts = translator.tales(expr)
stream = generation.CodeIO(symbols=config.SYMBOLS)
@@ -46,10 +47,22 @@
raise RuntimeError, "Can't locate template frame."
_locals = frame.f_locals
- _locals.update(symbol_mapping)
+ _locals.update(symbol_mapping)
+
+ # to support dynamic scoping (like in templates), we must
+ # transform the code to take the scope locals into account; for
+ # efficiency, this is cached for reuse
+ code_cache_key = key, tuple(_locals)
+ try:
+ code = _expr_cache[code_cache_key]
+ except KeyError:
+ suite = codegen.Suite(source, _locals)
+ code = compiler.compile(
+ suite.source, 'dynamic_path_expression.py', 'exec')
+ _expr_cache[code_cache_key] = code
# execute code and return evaluation
- exec source in _locals
+ exec code in codegen.lookup_globals.copy(), _locals
return _locals['result']
def evaluate_path(expr):
More information about the Checkins
mailing list