Premiere version : mise en route du suivi.
[auf_roundup.git] / roundup / cgi / PageTemplates / .svn / text-base / PythonExpr.py.svn-base
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
22 from TALES import CompilerError
23 from sys import exc_info
24
25 class getSecurityManager:
26     '''Null security manager'''
27     def validate(self, *args, **kwargs):
28         return 1
29     addContext = removeContext = validateValue = validate
30
31 class 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
76 class 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