############################################################################## # # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE # ############################################################################## """Generic Python Expression Handler """ __version__='$Revision: 1.1 $'[11:-2] from hdTALES import CompilerError from string import strip, split, join, replace, lstrip from sys import exc_info class getSecurityManager: '''Null security manager''' def validate(self, *args, **kwargs): return 1 addContext = removeContext = validateValue = validate class PythonExpr: def __init__(self, name, expr, engine): self.expr = expr = replace(strip(expr), '\n', ' ') try: d = {} exec 'def f():\n return %s\n' % strip(expr) in d self._f = d['f'] except: raise CompilerError, ('Python expression error:\n' '%s: %s') % exc_info()[:2] self._get_used_names() def _get_used_names(self): self._f_varnames = vnames = [] for vname in self._f.func_code.co_names: if vname[0] not in '$_': vnames.append(vname) 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: 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() def __str__(self): return 'Python expression "%s"' % self.expr def __repr__(self): return '' % self.expr class ExprTypeProxy: '''Class that proxies access to an expression type handler''' def __init__(self, name, handler, econtext): self._name = name self._handler = handler self._econtext = econtext def __call__(self, text): return self._handler(self._name, text, self._econtext._engine)(self._econtext)