Mercurial > p > roundup > code
diff PageTemplates/PythonExpr.py @ 984:a3a8ac7b8c40
Adding PageTemplates to the dist
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Fri, 30 Aug 2002 08:27:34 +0000 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PageTemplates/PythonExpr.py Fri Aug 30 08:27:34 2002 +0000 @@ -0,0 +1,82 @@ +############################################################################## +# +# 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 TALES 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 '<PythonExpr %s>' % 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) +
