Code

add line to rego email to help URL detection (sf bug 906247)
[roundup.git] / roundup / cgi / PageTemplates / PythonExpr.py
1 ##############################################################################
2 #
3 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
4
5 # This software is subject to the provisions of the Zope Public License,
6 # Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
10 # FOR A PARTICULAR PURPOSE
11
12 ##############################################################################
14 """Generic Python Expression Handler
16 Modified for Roundup 0.5 release:
18 - more informative traceback info
20 """
21 __docformat__ = 'restructuredtext'
23 __version__='$Revision: 1.5 $'[11:-2]
25 from TALES import CompilerError
26 from string import strip, split, join, replace, lstrip
27 from sys import exc_info
29 class getSecurityManager:
30     '''Null security manager'''
31     def validate(self, *args, **kwargs):
32         return 1
33     addContext = removeContext = validateValue = validate
35 class PythonExpr:
36     def __init__(self, name, expr, engine):
37         self.expr = expr = replace(strip(expr), '\n', ' ')
38         try:
39             d = {}
40             exec 'def f():\n return %s\n' % strip(expr) in d
41             self._f = d['f']
42         except:
43             raise CompilerError, ('Python expression error:\n'
44                                   '%s: %s') % exc_info()[:2]
45         self._get_used_names()
47     def _get_used_names(self):
48         self._f_varnames = vnames = []
49         for vname in self._f.func_code.co_names:
50             if vname[0] not in '$_':
51                 vnames.append(vname)
53     def _bind_used_names(self, econtext):
54         # Bind template variables
55         names = {}
56         vars = econtext.vars
57         getType = econtext.getCompiler().getTypes().get
58         for vname in self._f_varnames:
59             has, val = vars.has_get(vname)
60             if not has:
61                 has = val = getType(vname)
62                 if has:
63                     val = ExprTypeProxy(vname, val, econtext)
64             if has:
65                 names[vname] = val
66         return names
68     def __call__(self, econtext):
69         __traceback_info__ = 'python expression "%s"'%self.expr
70         f = self._f
71         f.func_globals.update(self._bind_used_names(econtext))        
72         return f()
74     def __str__(self):
75         return 'Python expression "%s"' % self.expr
76     def __repr__(self):
77         return '<PythonExpr %s>' % self.expr
79 class ExprTypeProxy:
80     '''Class that proxies access to an expression type handler'''
81     def __init__(self, name, handler, econtext):
82         self._name = name
83         self._handler = handler
84         self._econtext = econtext
85     def __call__(self, text):
86         return self._handler(self._name, text,
87                              self._econtext.getCompiler())(self._econtext)