[Zope-Checkins] CVS: Zope3/lib/python/Zope/PageTemplate - PythonExpr.py:1.1.2.6
Shane Hathaway
shane@cvs.zope.org
Wed, 13 Mar 2002 23:01:28 -0500
Update of /cvs-repository/Zope3/lib/python/Zope/PageTemplate
In directory cvs.zope.org:/tmp/cvs-serv11927
Modified Files:
Tag: Zope-3x-branch
PythonExpr.py
Log Message:
- Simplified a lot. There's no reason we can't just use Python's compile()
builtin.
- Renamed the attribute "expr" to "text", which more clearly expresses what
you'd expect to put in it.
=== Zope3/lib/python/Zope/PageTemplate/PythonExpr.py 1.1.2.5 => 1.1.2.6 ===
__version__ = '$Revision$'[11:-2]
-from TALES import CompilerError
-from sys import exc_info
-
-class NullSecurityManager:
- '''Null security manager'''
- def __init__(self):
- self._stack = []
- def validate(self, name, value):
- pass
- def validateValue(self, value):
- pass
- def pushExecutable(self, context):
- self._stack.append(context)
- def popExecutable(self):
- self._stack.pop()
-
-def getSecurityManager(null_manager=NullSecurityManager()):
- return null_manager
+_marker = object()
class PythonExpr:
def __init__(self, name, expr, engine):
- self.expr = expr = expr.strip().replace('\n', ' ')
- try:
- d = {}
- exec 'def f():\n return %s\n' % expr.strip() in d
- self._f = d['f']
- except:
- raise CompilerError, ('Python expression error:\n'
- '%s: %s') % exc_info()[:2]
+ text = expr.replace('\n', ' ').strip()
+ self.text = text
+ # The next line can legally raise SyntaxError.
+ self._code = compile(text, '<string>', 'eval')
self._get_used_names()
def _get_used_names(self):
- self._f_varnames = vnames = []
- for vname in self._f.func_code.co_names:
+ vnames = []
+ for vname in self._code.co_names:
if vname[0] not in '$_':
vnames.append(vname)
+ self._varnames = vnames
def _bind_used_names(self, econtext):
# Bind template variables
names = {}
vars = econtext.vars
getType = econtext._engine.getTypes().get
- for vname in self._f_varnames:
- has, val = vars.has_get(vname)
- if not has:
- has = val = getType(vname)
- if has:
- val = ExprTypeProxy(vname, val, econtext)
- if has:
+ marker = _marker
+ for vname in self._varnames:
+ val = vars.get(vname, marker)
+ if val is not marker:
names[vname] = val
+ else:
+ # Fall back to using expression types as variable values.
+ val = getType(vname)
+ if val is not None:
+ val = ExprTypeProxy(vname, val, econtext)
+ names[vname] = val
return names
def __call__(self, econtext):
- __traceback_info__ = self.expr
- f = self._f
- f.func_globals.update(self._bind_used_names(econtext))
- return f()
+ __traceback_info__ = self.text
+ vars = self._bind_used_names(econtext)
+ return eval(self._code, vars)
def __str__(self):
- return 'Python expression "%s"' % self.expr
+ return 'Python expression "%s"' % self.text
+
def __repr__(self):
- return '<PythonExpr %s>' % self.expr
+ return '<PythonExpr %s>' % self.text
+
class ExprTypeProxy:
'''Class that proxies access to an expression type handler'''
@@ -81,7 +65,7 @@
self._name = name
self._handler = handler
self._econtext = econtext
+
def __call__(self, text):
return self._handler(self._name, text,
self._econtext._engine)(self._econtext)
-