annotate roundup/cgi/PageTemplates/Expressions.py @ 8540:e8d1da6e3571

bug: fix traceback in roundup-admin init with bad config values initialize accepts setting values for config.ini file settings. If they are not valid, you got a python traceback. ConfigurationError exceptions are now trapped. The admin.py's usageError_feedback method is used to inform the user. Also the feedback message now starts with a newline making it easier to read by separating it from command that caused the issue.
author John Rouillard <rouilj@ieee.org>
date Mon, 23 Mar 2026 13:18:41 -0400
parents 33b25e51e127
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 #
2663
5f9e00836006 update comment
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
15 # 1. removed all Zope-specific code (doesn't even try to import that stuff now)
5f9e00836006 update comment
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
16 # 2. removed all Acquisition
5f9e00836006 update comment
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
17 # 3. removed blocking of leading-underscore URL components
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
18
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
19 """Page Template Expression Engine
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
20
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
21 Page Template-specific implementation of TALES, with handlers
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
22 for Python expressions, string literals, and paths.
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
23 """
1071
c08b3820edd1 Adhering to ZPL
Richard Jones <richard@users.sourceforge.net>
parents: 1065
diff changeset
24
5812
33b25e51e127 More fixes for: DeprecationWarning: Using or importing the ABCs from
John Rouillard <rouilj@ieee.org>
parents: 5406
diff changeset
25 import re, sys
33b25e51e127 More fixes for: DeprecationWarning: Using or importing the ABCs from
John Rouillard <rouilj@ieee.org>
parents: 5406
diff changeset
26 try:
33b25e51e127 More fixes for: DeprecationWarning: Using or importing the ABCs from
John Rouillard <rouilj@ieee.org>
parents: 5406
diff changeset
27 from collections.abc import Callable
33b25e51e127 More fixes for: DeprecationWarning: Using or importing the ABCs from
John Rouillard <rouilj@ieee.org>
parents: 5406
diff changeset
28 except ImportError:
33b25e51e127 More fixes for: DeprecationWarning: Using or importing the ABCs from
John Rouillard <rouilj@ieee.org>
parents: 5406
diff changeset
29 from collections import Callable
33b25e51e127 More fixes for: DeprecationWarning: Using or importing the ABCs from
John Rouillard <rouilj@ieee.org>
parents: 5406
diff changeset
30
5388
d26921b851c3 Python 3 preparation: make relative imports explicit.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5378
diff changeset
31 from .TALES import Engine, CompilerError, _valid_name, NAME_RE, \
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
32 Undefined, Default, _parse_expr
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
33
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
34
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
35 _engine = None
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
36 def getEngine():
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
37 global _engine
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
38 if _engine is None:
5388
d26921b851c3 Python 3 preparation: make relative imports explicit.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5378
diff changeset
39 from .PathIterator import Iterator
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
40 _engine = Engine(Iterator)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
41 installHandlers(_engine)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
42 return _engine
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
43
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
44 def installHandlers(engine):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
45 reg = engine.registerType
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
46 pe = PathExpr
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
47 for pt in ('standard', 'path', 'exists', 'nocall'):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
48 reg(pt, pe)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
49 reg('string', StringExpr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
50 reg('python', PythonExpr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
51 reg('not', NotExpr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
52 reg('defer', DeferExpr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
53
5388
d26921b851c3 Python 3 preparation: make relative imports explicit.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5378
diff changeset
54 from .PythonExpr import getSecurityManager, PythonExpr
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
55 guarded_getattr = getattr
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
56 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
57 from zExceptions import Unauthorized
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
58 except ImportError:
5265
63868084b8bb Python 2 and 3 support. Convert Exception to BaseException. TAL and
John Rouillard <rouilj@ieee.org>
parents: 5248
diff changeset
59 class Unauthorized(BaseException):
4238
445e1bc8b1df remove use of string exception
Richard Jones <richard@users.sourceforge.net>
parents: 2663
diff changeset
60 pass
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
61
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
62 def acquisition_security_filter(orig, inst, name, v, real_validate):
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
63 if real_validate(orig, inst, name, v):
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
64 return 1
5378
35ea9b1efc14 Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5377
diff changeset
65 raise Unauthorized(name)
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
66
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
67 def call_with_ns(f, ns, arg=1):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
68 if arg==2:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
69 return f(None, ns)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
70 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
71 return f(ns)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
72
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
73 class _SecureModuleImporter:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
74 """Simple version of the importer for use with trusted code."""
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
75 __allow_access_to_unprotected_subobjects__ = 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
76 def __getitem__(self, module):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
77 __import__(module)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
78 return sys.modules[module]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
79
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
80 SecureModuleImporter = _SecureModuleImporter()
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
81
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
82 Undefs = (Undefined, AttributeError, KeyError,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
83 TypeError, IndexError, Unauthorized)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
84
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
85 def render(ob, ns):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
86 """
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
87 Calls the object, possibly a document template, or just returns it if
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
88 not callable. (From DT_Util.py)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
89 """
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
90 if hasattr(ob, '__render_with_namespace__'):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
91 ob = call_with_ns(ob.__render_with_namespace__, ns)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
92 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
93 base = ob
5812
33b25e51e127 More fixes for: DeprecationWarning: Using or importing the ABCs from
John Rouillard <rouilj@ieee.org>
parents: 5406
diff changeset
94 if isinstance(base, Callable):
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
95 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
96 if getattr(base, 'isDocTemp', 0):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
97 ob = call_with_ns(ob, ns, 2)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
98 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
99 ob = ob()
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 4570
diff changeset
100 except AttributeError as n:
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
101 if str(n) != '__call__':
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
102 raise
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
103 return ob
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
104
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
105 class SubPathExpr:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
106 def __init__(self, path):
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
107 self._path = path = path.strip().split('/')
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
108 self._base = base = path.pop(0)
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
109 if base and not _valid_name(base):
5378
35ea9b1efc14 Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5377
diff changeset
110 raise CompilerError('Invalid variable name "%s"' % base)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
111 # Parse path
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
112 self._dp = dp = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
113 for i in range(len(path)):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
114 e = path[i]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
115 if e[:1] == '?' and _valid_name(e[1:]):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
116 dp.append((i, e[1:]))
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
117 dp.reverse()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
118
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
119 def _eval(self, econtext,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
120 list=list, isinstance=isinstance, StringType=type('')):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
121 vars = econtext.vars
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
122 path = self._path
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
123 if self._dp:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
124 path = list(path) # Copy!
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
125 for i, varname in self._dp:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
126 val = vars[varname]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
127 if isinstance(val, StringType):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
128 path[i] = val
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
129 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
130 # If the value isn't a string, assume it's a sequence
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
131 # of path names.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
132 path[i:i+1] = list(val)
1065
0f9aa62917bd much nicer error messages when there's a templating error
Richard Jones <richard@users.sourceforge.net>
parents: 1049
diff changeset
133 base = self._base
1136
7e193bbda38e added generic item editing
Richard Jones <richard@users.sourceforge.net>
parents: 1101
diff changeset
134 __traceback_info__ = 'path expression "%s"'%('/'.join(self._path))
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
135 if base == 'CONTEXTS' or not base:
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
136 ob = econtext.contexts
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
137 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
138 ob = vars[base]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
139 if isinstance(ob, DeferWrapper):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
140 ob = ob()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
141 if path:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
142 ob = restrictedTraverse(ob, path, getSecurityManager())
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
143 return ob
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
144
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
145 class PathExpr:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
146 def __init__(self, name, expr, engine):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
147 self._s = expr
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
148 self._name = name
1233
69bf0d381fd7 Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents: 1181
diff changeset
149 self._hybrid = 0
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
150 paths = expr.split('|')
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
151 self._subexprs = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
152 add = self._subexprs.append
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
153 for i in range(len(paths)):
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
154 path = paths[i].lstrip()
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
155 if _parse_expr(path):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
156 # This part is the start of another expression type,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
157 # so glue it back together and compile it.
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
158 add(engine.compile(('|'.join(paths[i:]).lstrip())))
1233
69bf0d381fd7 Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents: 1181
diff changeset
159 self._hybrid = 1
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
160 break
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
161 add(SubPathExpr(path)._eval)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
162
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
163 def _exists(self, econtext):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
164 for expr in self._subexprs:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
165 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
166 expr(econtext)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
167 except Undefs:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
168 pass
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
169 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
170 return 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
171 return 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
172
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
173 def _eval(self, econtext,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
174 isinstance=isinstance, StringType=type(''), render=render):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
175 for expr in self._subexprs[:-1]:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
176 # Try all but the last subexpression, skipping undefined ones.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
177 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
178 ob = expr(econtext)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
179 except Undefs:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
180 pass
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
181 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
182 break
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
183 else:
1233
69bf0d381fd7 Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents: 1181
diff changeset
184 # On the last subexpression allow exceptions through, and
69bf0d381fd7 Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents: 1181
diff changeset
185 # don't autocall if the expression was not a subpath.
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
186 ob = self._subexprs[-1](econtext)
1233
69bf0d381fd7 Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents: 1181
diff changeset
187 if self._hybrid:
69bf0d381fd7 Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents: 1181
diff changeset
188 return ob
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
189
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
190 if self._name == 'nocall' or isinstance(ob, StringType):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
191 return ob
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
192 # Return the rendered object
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
193 return render(ob, econtext.vars)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
194
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
195 def __call__(self, econtext):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
196 if self._name == 'exists':
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
197 return self._exists(econtext)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
198 return self._eval(econtext)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
199
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
200 def __str__(self):
5377
12fe83f90f0d Python 3 preparation: use repr() instead of ``.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5265
diff changeset
201 return '%s expression %s' % (self._name, repr(self._s))
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
202
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
203 def __repr__(self):
5377
12fe83f90f0d Python 3 preparation: use repr() instead of ``.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5265
diff changeset
204 return '%s:%s' % (self._name, repr(self._s))
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
205
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
206
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
207 _interp = re.compile(r'\$(%(n)s)|\${(%(n)s(?:/[^}]*)*)}' % {'n': NAME_RE})
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
208
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
209 class StringExpr:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
210 def __init__(self, name, expr, engine):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
211 self._s = expr
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
212 if '%' in expr:
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
213 expr = expr.replace('%', '%%')
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
214 self._vars = vars = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
215 if '$' in expr:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
216 parts = []
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
217 for exp in expr.split('$$'):
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
218 if parts: parts.append('$')
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
219 m = _interp.search(exp)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
220 while m is not None:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
221 parts.append(exp[:m.start()])
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
222 parts.append('%s')
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
223 vars.append(PathExpr('path', m.group(1) or m.group(2),
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
224 engine))
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
225 exp = exp[m.end():]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
226 m = _interp.search(exp)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
227 if '$' in exp:
5378
35ea9b1efc14 Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5377
diff changeset
228 raise CompilerError(
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
229 '$ must be doubled or followed by a simple path')
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
230 parts.append(exp)
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
231 expr = ''.join(parts)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
232 self._expr = expr
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
233
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
234 def __call__(self, econtext):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
235 vvals = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
236 for var in self._vars:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
237 v = var(econtext)
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
238 # I hope this isn't in use anymore.
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
239 ## if isinstance(v, Exception):
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
240 ## raise v
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
241 vvals.append(v)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
242 return self._expr % tuple(vvals)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
243
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
244 def __str__(self):
5377
12fe83f90f0d Python 3 preparation: use repr() instead of ``.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5265
diff changeset
245 return 'string expression %s' % repr(self._s)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
246
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
247 def __repr__(self):
5377
12fe83f90f0d Python 3 preparation: use repr() instead of ``.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5265
diff changeset
248 return 'string:%s' % repr(self._s)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
249
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
250 class NotExpr:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
251 def __init__(self, name, expr, compiler):
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
252 self._s = expr = expr.lstrip()
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
253 self._c = compiler.compile(expr)
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
254
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
255 def __call__(self, econtext):
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
256 # We use the (not x) and 1 or 0 formulation to avoid changing
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
257 # the representation of the result in Python 2.3, where the
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
258 # result of "not" becomes an instance of bool.
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
259 return (not econtext.evaluateBoolean(self._c)) and 1 or 0
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
260
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
261 def __repr__(self):
5377
12fe83f90f0d Python 3 preparation: use repr() instead of ``.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5265
diff changeset
262 return 'not:%s' % repr(self._s)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
263
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
264 class DeferWrapper:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
265 def __init__(self, expr, econtext):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
266 self._expr = expr
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
267 self._econtext = econtext
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
268
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
269 def __str__(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
270 return str(self())
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
271
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
272 def __call__(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
273 return self._expr(self._econtext)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
274
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
275 class DeferExpr:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
276 def __init__(self, name, expr, compiler):
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
277 self._s = expr = expr.lstrip()
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
278 self._c = compiler.compile(expr)
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
279
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
280 def __call__(self, econtext):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
281 return DeferWrapper(self._c, econtext)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
282
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
283 def __repr__(self):
5377
12fe83f90f0d Python 3 preparation: use repr() instead of ``.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5265
diff changeset
284 return 'defer:%s' % repr(self._s)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
285
2351
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
286 class TraversalError:
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
287 def __init__(self, path, name):
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
288 self.path = path
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
289 self.name = name
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
290
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
291
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
292
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
293 def restrictedTraverse(object, path, securityManager,
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
294 get=getattr, has=hasattr, N=None, M=[],
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
295 TupleType=type(()) ):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
296
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
297 REQUEST = {'path': path}
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
298 REQUEST['TraversalRequestNameStack'] = path = path[:] # Copy!
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
299 path.reverse()
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
300 validate = securityManager.validate
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
301 __traceback_info__ = REQUEST
2351
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
302 done = []
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
303 while path:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
304 name = path.pop()
2351
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
305 __traceback_info__ = TraversalError(done, name)
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
306
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
307 if isinstance(name, TupleType):
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
308 object = object(*name)
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
309 continue
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
310
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
311 if not name:
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
312 # Skip directly to item access
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
313 o = object[name]
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
314 # Check access to the item.
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
315 if not validate(object, object, name, o):
5378
35ea9b1efc14 Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5377
diff changeset
316 raise Unauthorized(name)
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
317 object = o
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
318 continue
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
319
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
320 # Try an attribute.
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
321 o = guarded_getattr(object, name, M)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
322 if o is M:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
323 # Try an item.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
324 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
325 # XXX maybe in Python 2.2 we can just check whether
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
326 # the object has the attribute "__getitem__"
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
327 # instead of blindly catching exceptions.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
328 o = object[name]
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 4570
diff changeset
329 except AttributeError as exc:
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
330 if str(exc).find('__getitem__') >= 0:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
331 # The object does not support the item interface.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
332 # Try to re-raise the original attribute error.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
333 # XXX I think this only happens with
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
334 # ExtensionClass instances.
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
335 guarded_getattr(object, name)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
336 raise
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 4570
diff changeset
337 except TypeError as exc:
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
338 if str(exc).find('unsubscriptable') >= 0:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
339 # The object does not support the item interface.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
340 # Try to re-raise the original attribute error.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
341 # XXX This is sooooo ugly.
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
342 guarded_getattr(object, name)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
343 raise
2351
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
344 done.append((name, o))
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
345 object = o
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
346
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
347 return object

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