Correction crash
[auf_roundup.git] / build / lib / roundup / cgi / PageTemplates / PythonExpr.py
CommitLineData
c638d827
CR
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##############################################################################
13# Modified for Roundup:
14#
15# 1. more informative traceback info
16
17"""Generic Python Expression Handler
18"""
19
20__version__='$Revision: 1.6 $'[11:-2]
21
22from TALES import CompilerError
23from sys import exc_info
24
25class getSecurityManager:
26 '''Null security manager'''
27 def validate(self, *args, **kwargs):
28 return 1
29 addContext = removeContext = validateValue = validate
30
31class PythonExpr:
32 def __init__(self, name, expr, engine):
33 self.expr = expr = expr.strip().replace('\n', ' ')
34 try:
35 d = {}
36 exec 'def f():\n return %s\n' % expr.strip() in d
37 self._f = d['f']
38 except:
39 raise CompilerError, ('Python expression error:\n'
40 '%s: %s') % exc_info()[:2]
41 self._get_used_names()
42
43 def _get_used_names(self):
44 self._f_varnames = vnames = []
45 for vname in self._f.func_code.co_names:
46 if vname[0] not in '$_':
47 vnames.append(vname)
48
49 def _bind_used_names(self, econtext, _marker=[]):
50 # Bind template variables
51 names = {'CONTEXTS': econtext.contexts}
52 vars = econtext.vars
53 getType = econtext.getCompiler().getTypes().get
54 for vname in self._f_varnames:
55 val = vars.get(vname, _marker)
56 if val is _marker:
57 has = val = getType(vname)
58 if has:
59 val = ExprTypeProxy(vname, val, econtext)
60 names[vname] = val
61 else:
62 names[vname] = val
63 return names
64
65 def __call__(self, econtext):
66 __traceback_info__ = 'python expression "%s"'%self.expr
67 f = self._f
68 f.func_globals.update(self._bind_used_names(econtext))
69 return f()
70
71 def __str__(self):
72 return 'Python expression "%s"' % self.expr
73 def __repr__(self):
74 return '<PythonExpr %s>' % self.expr
75
76class ExprTypeProxy:
77 '''Class that proxies access to an expression type handler'''
78 def __init__(self, name, handler, econtext):
79 self._name = name
80 self._handler = handler
81 self._econtext = econtext
82 def __call__(self, text):
83 return self._handler(self._name, text,
84 self._econtext.getCompiler())(self._econtext)
85