annotate roundup/cgi/PageTemplates/TALES.py @ 8241:741ea8a86012

fix: issue2551374. Error handling for filter expressions. Errors in filter expressions are now reported. The UI needs some work but even the current code is helpful when debugging filter expressions. mlink_expr: defines/raises ExpressionError(error string template, context=dict()) raises ExpressionError when it detects errors when popping arguments off stack raises ExpressionError when more than one element left on the stack before returning also ruff fix to group boolean expression with parens back_anydbm.py, rdbms_common.py: catches ExpressionError, augments context with class and attribute being searched. raises the exception for both link and multilink relations client.py catches ExpressionError returning a basic error page. The page is a dead end. There are no links or anything for the user to move forward. The user has to go back, possibly refresh the page (because the submit button may be disalbled) re-enter the query and try again. This needs to be improved. test_liveserver.py test the error page generated by client.py db_test_base unit tests for filter with too few arguments, too many arguments, check all repr and str formats.
author John Rouillard <rouilj@ieee.org>
date Mon, 30 Dec 2024 20:22:55 -0500
parents bd4097fa0671
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1 ##############################################################################
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2 #
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
3 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
4 #
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
5 # This software is subject to the provisions of the Zope Public License,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
6 # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
10 # FOR A PARTICULAR PURPOSE
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
11 #
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
12 ##############################################################################
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
13 # Modified for Roundup:
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
14 #
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
15 # 1. changed imports to import from roundup.cgi
2663
5f9e00836006 update comment
Richard Jones <richard@users.sourceforge.net>
parents: 2662
diff changeset
16 # 2. implemented ustr as str (removes import from DocumentTemplate)
5f9e00836006 update comment
Richard Jones <richard@users.sourceforge.net>
parents: 2662
diff changeset
17 # 3. removed import and use of Unauthorized from zExceptions
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
18 """TALES
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
19
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
20 An implementation of a generic TALES engine
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
21 """
1071
c08b3820edd1 Adhering to ZPL
Richard Jones <richard@users.sourceforge.net>
parents: 1049
diff changeset
22
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
23 import re, sys
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
24 from roundup.cgi import ZTUtils
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
25 from weakref import ref
5388
d26921b851c3 Python 3 preparation: make relative imports explicit.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5381
diff changeset
26 from .MultiMapping import MultiMapping
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
27
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
28 ustr = str
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
29
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
30 StringType = type('')
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
31
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
32 NAME_RE = r"[a-zA-Z][a-zA-Z0-9_]*"
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
33 _parse_expr = re.compile(r"(%s):" % NAME_RE).match
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
34 _valid_name = re.compile('%s$' % NAME_RE).match
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
35
5265
63868084b8bb Python 2 and 3 support. Convert Exception to BaseException. TAL and
John Rouillard <rouilj@ieee.org>
parents: 4570
diff changeset
36 class TALESError(BaseException):
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
37 """Error during TALES expression evaluation"""
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
38
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
39 class Undefined(TALESError):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
40 '''Exception raised on traversal of an undefined path'''
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
41
5265
63868084b8bb Python 2 and 3 support. Convert Exception to BaseException. TAL and
John Rouillard <rouilj@ieee.org>
parents: 4570
diff changeset
42 class RegistrationError(BaseException):
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
43 '''TALES Type Registration Error'''
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
44
5265
63868084b8bb Python 2 and 3 support. Convert Exception to BaseException. TAL and
John Rouillard <rouilj@ieee.org>
parents: 4570
diff changeset
45 class CompilerError(BaseException):
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
46 '''TALES Compiler Error'''
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
47
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
48 class Default:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
49 '''Retain Default'''
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
50 Default = Default()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
51
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
52 class SafeMapping(MultiMapping):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
53 '''Mapping with security declarations and limited method exposure.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
54
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
55 Since it subclasses MultiMapping, this class can be used to wrap
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
56 one or more mapping objects. Restricted Python code will not be
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
57 able to mutate the SafeMapping or the wrapped mappings, but will be
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
58 able to read any value.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
59 '''
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
60 __allow_access_to_unprotected_subobjects__ = 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
61 push = pop = None
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
62
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
63 _push = MultiMapping.push
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
64 _pop = MultiMapping.pop
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
65
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
66
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
67 class Iterator(ZTUtils.Iterator):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
68 def __init__(self, name, seq, context):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
69 ZTUtils.Iterator.__init__(self, seq)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
70 self.name = name
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
71 self._context_ref = ref(context)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
72
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
73 def next(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
74 if ZTUtils.Iterator.next(self):
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
75 context = self._context_ref()
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
76 if context is not None:
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
77 context.setLocal(self.name, self.item)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
78 return 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
79 return 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
80
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
81
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
82 class ErrorInfo:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
83 """Information about an exception passed to an on-error handler."""
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
84 __allow_access_to_unprotected_subobjects__ = 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
85
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
86 def __init__(self, err, position=(None, None)):
5265
63868084b8bb Python 2 and 3 support. Convert Exception to BaseException. TAL and
John Rouillard <rouilj@ieee.org>
parents: 4570
diff changeset
87 if isinstance(err, BaseException):
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
88 self.type = err.__class__
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
89 self.value = err
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
90 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
91 self.type = err
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
92 self.value = None
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
93 self.lineno = position[0]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
94 self.offset = position[1]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
95
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
96
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
97 class Engine:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
98 '''Expression Engine
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
99
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
100 An instance of this class keeps a mutable collection of expression
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
101 type handlers. It can compile expression strings by delegating to
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
102 these handlers. It can provide an expression Context, which is
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
103 capable of holding state and evaluating compiled expressions.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
104 '''
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
105 Iterator = Iterator
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
106
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
107 def __init__(self, Iterator=None):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
108 self.types = {}
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
109 if Iterator is not None:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
110 self.Iterator = Iterator
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
111
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
112 def registerType(self, name, handler):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
113 if not _valid_name(name):
5378
35ea9b1efc14 Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5377
diff changeset
114 raise RegistrationError('Invalid Expression type "%s".' % name)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
115 types = self.types
5381
0942fe89e82e Python 3 preparation: change "x.has_key(y)" to "y in x".
Joseph Myers <jsm@polyomino.org.uk>
parents: 5378
diff changeset
116 if name in types:
5378
35ea9b1efc14 Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5377
diff changeset
117 raise RegistrationError(
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
118 'Multiple registrations for Expression type "%s".' %
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
119 name)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
120 types[name] = handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
121
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
122 def getTypes(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
123 return self.types
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
124
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
125 def compile(self, expression):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
126 m = _parse_expr(expression)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
127 if m:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
128 type = m.group(1)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
129 expr = expression[m.end():]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
130 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
131 type = "standard"
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
132 expr = expression
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
133 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
134 handler = self.types[type]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
135 except KeyError:
5378
35ea9b1efc14 Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5377
diff changeset
136 raise CompilerError(
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
137 'Unrecognized expression type "%s".' % type)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
138 return handler(type, expr, self)
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
139
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
140 def getContext(self, contexts=None, **kwcontexts):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
141 if contexts is not None:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
142 if kwcontexts:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
143 kwcontexts.update(contexts)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
144 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
145 kwcontexts = contexts
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
146 return Context(self, kwcontexts)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
147
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
148 def getCompilerError(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
149 return CompilerError
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
150
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
151 class Context:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
152 '''Expression Context
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
153
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
154 An instance of this class holds context information that it can
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
155 use to evaluate compiled expressions.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
156 '''
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
157
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
158 _context_class = SafeMapping
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
159 position = (None, None)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
160 source_file = None
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
161
1257
93b80ad11ca8 merged Zope Collector #372 fix from ZPT CVS trunk
Richard Jones <richard@users.sourceforge.net>
parents: 1219
diff changeset
162 def __init__(self, compiler, contexts):
93b80ad11ca8 merged Zope Collector #372 fix from ZPT CVS trunk
Richard Jones <richard@users.sourceforge.net>
parents: 1219
diff changeset
163 self._compiler = compiler
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
164 self.contexts = contexts
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
165 contexts['nothing'] = None
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
166 contexts['default'] = Default
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
167
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
168 self.repeat_vars = rv = {}
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
169 # Wrap this, as it is visible to restricted code
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
170 contexts['repeat'] = rep = self._context_class(rv)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
171 contexts['loop'] = rep # alias
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
172
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
173 self.global_vars = gv = contexts.copy()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
174 self.local_vars = lv = {}
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
175 self.vars = self._context_class(gv, lv)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
176
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
177 # Keep track of what needs to be popped as each scope ends.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
178 self._scope_stack = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
179
1257
93b80ad11ca8 merged Zope Collector #372 fix from ZPT CVS trunk
Richard Jones <richard@users.sourceforge.net>
parents: 1219
diff changeset
180 def getCompiler(self):
93b80ad11ca8 merged Zope Collector #372 fix from ZPT CVS trunk
Richard Jones <richard@users.sourceforge.net>
parents: 1219
diff changeset
181 return self._compiler
93b80ad11ca8 merged Zope Collector #372 fix from ZPT CVS trunk
Richard Jones <richard@users.sourceforge.net>
parents: 1219
diff changeset
182
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
183 def beginScope(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
184 self._scope_stack.append([self.local_vars.copy()])
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
185
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
186 def endScope(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
187 scope = self._scope_stack.pop()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
188 self.local_vars = lv = scope[0]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
189 v = self.vars
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
190 v._pop()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
191 v._push(lv)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
192 # Pop repeat variables, if any
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
193 i = len(scope) - 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
194 while i:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
195 name, value = scope[i]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
196 if value is None:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
197 del self.repeat_vars[name]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
198 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
199 self.repeat_vars[name] = value
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
200 i = i - 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
201
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
202 def setLocal(self, name, value):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
203 self.local_vars[name] = value
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
204
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
205 def setGlobal(self, name, value):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
206 self.global_vars[name] = value
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
207
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
208 def setRepeat(self, name, expr):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
209 expr = self.evaluate(expr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
210 if not expr:
1257
93b80ad11ca8 merged Zope Collector #372 fix from ZPT CVS trunk
Richard Jones <richard@users.sourceforge.net>
parents: 1219
diff changeset
211 return self._compiler.Iterator(name, (), self)
93b80ad11ca8 merged Zope Collector #372 fix from ZPT CVS trunk
Richard Jones <richard@users.sourceforge.net>
parents: 1219
diff changeset
212 it = self._compiler.Iterator(name, expr, self)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
213 old_value = self.repeat_vars.get(name)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
214 self._scope_stack[-1].append((name, old_value))
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
215 self.repeat_vars[name] = it
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
216 return it
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
217
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
218 def evaluate(self, expression,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
219 isinstance=isinstance, StringType=StringType):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
220 if isinstance(expression, StringType):
1257
93b80ad11ca8 merged Zope Collector #372 fix from ZPT CVS trunk
Richard Jones <richard@users.sourceforge.net>
parents: 1219
diff changeset
221 expression = self._compiler.compile(expression)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
222 __traceback_supplement__ = (
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
223 TALESTracebackSupplement, self, expression)
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
224 return expression(self)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
225
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
226 evaluateValue = evaluate
1219
9620f6782cb7 merge Zope Collector #580 fix from ZPT CVS trunk
Richard Jones <richard@users.sourceforge.net>
parents: 1071
diff changeset
227 evaluateBoolean = evaluate
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
228
1409
8dc60d87ab42 Fixed a backlog of bug reports, and worked on python 2.3 compatibility:
Richard Jones <richard@users.sourceforge.net>
parents: 1257
diff changeset
229 def evaluateText(self, expr):
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
230 text = self.evaluate(expr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
231 if text is Default or text is None:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
232 return text
5416
56c9bcdea47f Python 3 preparation: unicode.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5388
diff changeset
233 if isinstance(text, type(u'')):
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
234 return text
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
235 else:
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
236 return ustr(text)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
237
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
238 def evaluateStructure(self, expr):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
239 return self.evaluate(expr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
240 evaluateStructure = evaluate
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
241
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
242 def evaluateMacro(self, expr):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
243 # XXX Should return None or a macro definition
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
244 return self.evaluate(expr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
245 evaluateMacro = evaluate
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
246
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
247 def createErrorInfo(self, err, position):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
248 return ErrorInfo(err, position)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
249
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
250 def getDefault(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
251 return Default
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
252
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
253 def setSourceFile(self, source_file):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
254 self.source_file = source_file
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
255
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
256 def setPosition(self, position):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
257 self.position = position
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
258
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
259 class TALESTracebackSupplement:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
260 """Implementation of ITracebackSupplement"""
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
261 def __init__(self, context, expression):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
262 self.context = context
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
263 self.source_url = context.source_file
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
264 self.line = context.position[0]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
265 self.column = context.position[1]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
266 self.expression = repr(expression)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
267
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
268 def getInfo(self, as_html=0):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
269 import pprint
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
270 data = self.context.contexts.copy()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
271 s = pprint.pformat(data)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
272 if not as_html:
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
273 return ' - Names:\n %s' % s.replace('\n', '\n ')
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
274 else:
5837
883c9e90b403 Fix problem with cgi.escape being depricated a different way. This way
John Rouillard <rouilj@ieee.org>
parents: 5416
diff changeset
275 from roundup.anypy.html import html_escape
883c9e90b403 Fix problem with cgi.escape being depricated a different way. This way
John Rouillard <rouilj@ieee.org>
parents: 5416
diff changeset
276 return '<b>Names:</b><pre>%s</pre>' % (html_escape(s))
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
277
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
278
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
279 class SimpleExpr:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
280 '''Simple example of an expression type handler'''
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
281 def __init__(self, name, expr, engine):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
282 self._name = name
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
283 self._expr = expr
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
284 def __call__(self, econtext):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
285 return self._name, self._expr
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
286 def __repr__(self):
5377
12fe83f90f0d Python 3 preparation: use repr() instead of ``.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5265
diff changeset
287 return '<SimpleExpr %s %s>' % (self._name, repr(self._expr))

Roundup Issue Tracker: http://roundup-tracker.org/