Mercurial > p > roundup > code
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 |
| rev | line source |
|---|---|
| 1049 | 1 ############################################################################## |
| 2 # | |
| 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 | 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 | |
|
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 | 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 | 18 |
| 19 """Page Template Expression Engine | |
| 20 | |
| 21 Page Template-specific implementation of TALES, with handlers | |
| 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 | 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 | 34 |
| 35 _engine = None | |
| 36 def getEngine(): | |
| 37 global _engine | |
| 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 | 40 _engine = Engine(Iterator) |
| 41 installHandlers(_engine) | |
| 42 return _engine | |
| 43 | |
| 44 def installHandlers(engine): | |
| 45 reg = engine.registerType | |
| 46 pe = PathExpr | |
| 47 for pt in ('standard', 'path', 'exists', 'nocall'): | |
| 48 reg(pt, pe) | |
| 49 reg('string', StringExpr) | |
| 50 reg('python', PythonExpr) | |
| 51 reg('not', NotExpr) | |
| 52 reg('defer', DeferExpr) | |
| 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 | 56 try: |
| 57 from zExceptions import Unauthorized | |
| 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 | 67 def call_with_ns(f, ns, arg=1): |
| 68 if arg==2: | |
| 69 return f(None, ns) | |
| 70 else: | |
| 71 return f(ns) | |
| 72 | |
| 73 class _SecureModuleImporter: | |
| 74 """Simple version of the importer for use with trusted code.""" | |
| 75 __allow_access_to_unprotected_subobjects__ = 1 | |
| 76 def __getitem__(self, module): | |
| 77 __import__(module) | |
| 78 return sys.modules[module] | |
| 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 | 82 Undefs = (Undefined, AttributeError, KeyError, |
| 83 TypeError, IndexError, Unauthorized) | |
| 84 | |
| 85 def render(ob, ns): | |
| 86 """ | |
| 87 Calls the object, possibly a document template, or just returns it if | |
| 88 not callable. (From DT_Util.py) | |
| 89 """ | |
| 90 if hasattr(ob, '__render_with_namespace__'): | |
| 91 ob = call_with_ns(ob.__render_with_namespace__, ns) | |
| 92 else: | |
| 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 | 95 try: |
| 96 if getattr(base, 'isDocTemp', 0): | |
| 97 ob = call_with_ns(ob, ns, 2) | |
| 98 else: | |
| 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 | 101 if str(n) != '__call__': |
| 102 raise | |
| 103 return ob | |
| 104 | |
| 105 class SubPathExpr: | |
| 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 | 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 | 111 # Parse path |
| 112 self._dp = dp = [] | |
| 113 for i in range(len(path)): | |
| 114 e = path[i] | |
| 115 if e[:1] == '?' and _valid_name(e[1:]): | |
| 116 dp.append((i, e[1:])) | |
| 117 dp.reverse() | |
| 118 | |
| 119 def _eval(self, econtext, | |
| 120 list=list, isinstance=isinstance, StringType=type('')): | |
| 121 vars = econtext.vars | |
| 122 path = self._path | |
| 123 if self._dp: | |
| 124 path = list(path) # Copy! | |
| 125 for i, varname in self._dp: | |
| 126 val = vars[varname] | |
| 127 if isinstance(val, StringType): | |
| 128 path[i] = val | |
| 129 else: | |
| 130 # If the value isn't a string, assume it's a sequence | |
| 131 # of path names. | |
| 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 | 136 ob = econtext.contexts |
| 137 else: | |
| 138 ob = vars[base] | |
| 139 if isinstance(ob, DeferWrapper): | |
| 140 ob = ob() | |
| 141 if path: | |
| 142 ob = restrictedTraverse(ob, path, getSecurityManager()) | |
| 143 return ob | |
| 144 | |
| 145 class PathExpr: | |
| 146 def __init__(self, name, expr, engine): | |
| 147 self._s = expr | |
| 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 | 151 self._subexprs = [] |
| 152 add = self._subexprs.append | |
| 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 | 155 if _parse_expr(path): |
| 156 # This part is the start of another expression type, | |
| 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 | 160 break |
| 161 add(SubPathExpr(path)._eval) | |
| 162 | |
| 163 def _exists(self, econtext): | |
| 164 for expr in self._subexprs: | |
| 165 try: | |
| 166 expr(econtext) | |
| 167 except Undefs: | |
| 168 pass | |
| 169 else: | |
| 170 return 1 | |
| 171 return 0 | |
| 172 | |
| 173 def _eval(self, econtext, | |
| 174 isinstance=isinstance, StringType=type(''), render=render): | |
| 175 for expr in self._subexprs[:-1]: | |
| 176 # Try all but the last subexpression, skipping undefined ones. | |
| 177 try: | |
| 178 ob = expr(econtext) | |
| 179 except Undefs: | |
| 180 pass | |
| 181 else: | |
| 182 break | |
| 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 | 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 | 189 |
| 190 if self._name == 'nocall' or isinstance(ob, StringType): | |
| 191 return ob | |
| 192 # Return the rendered object | |
| 193 return render(ob, econtext.vars) | |
| 194 | |
| 195 def __call__(self, econtext): | |
| 196 if self._name == 'exists': | |
| 197 return self._exists(econtext) | |
| 198 return self._eval(econtext) | |
| 199 | |
| 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 | 202 |
| 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 | 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 | 208 |
| 209 class StringExpr: | |
| 210 def __init__(self, name, expr, engine): | |
| 211 self._s = expr | |
| 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 | 214 self._vars = vars = [] |
| 215 if '$' in expr: | |
| 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 | 218 if parts: parts.append('$') |
| 219 m = _interp.search(exp) | |
| 220 while m is not None: | |
| 221 parts.append(exp[:m.start()]) | |
| 222 parts.append('%s') | |
| 223 vars.append(PathExpr('path', m.group(1) or m.group(2), | |
| 224 engine)) | |
| 225 exp = exp[m.end():] | |
| 226 m = _interp.search(exp) | |
| 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 | 229 '$ must be doubled or followed by a simple path') |
| 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 | 232 self._expr = expr |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
233 |
| 1049 | 234 def __call__(self, econtext): |
| 235 vvals = [] | |
| 236 for var in self._vars: | |
| 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 | 241 vvals.append(v) |
| 242 return self._expr % tuple(vvals) | |
| 243 | |
| 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 | 246 |
| 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 | 249 |
| 250 class NotExpr: | |
| 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 | 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 | 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 | 260 |
| 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 | 263 |
| 264 class DeferWrapper: | |
| 265 def __init__(self, expr, econtext): | |
| 266 self._expr = expr | |
| 267 self._econtext = econtext | |
| 268 | |
| 269 def __str__(self): | |
| 270 return str(self()) | |
| 271 | |
| 272 def __call__(self): | |
| 273 return self._expr(self._econtext) | |
| 274 | |
| 275 class DeferExpr: | |
| 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 | 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 | 280 def __call__(self, econtext): |
| 281 return DeferWrapper(self._c, econtext) | |
| 282 | |
| 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 | 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 | 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 | 294 get=getattr, has=hasattr, N=None, M=[], |
| 295 TupleType=type(()) ): | |
| 296 | |
| 297 REQUEST = {'path': path} | |
| 298 REQUEST['TraversalRequestNameStack'] = path = path[:] # Copy! | |
| 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 | 303 while path: |
| 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 | 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 | 319 |
| 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 | 322 if o is M: |
| 323 # Try an item. | |
| 324 try: | |
| 325 # XXX maybe in Python 2.2 we can just check whether | |
| 326 # the object has the attribute "__getitem__" | |
| 327 # instead of blindly catching exceptions. | |
| 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 | 330 if str(exc).find('__getitem__') >= 0: |
| 331 # The object does not support the item interface. | |
| 332 # Try to re-raise the original attribute error. | |
| 333 # XXX I think this only happens with | |
| 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 | 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 | 338 if str(exc).find('unsubscriptable') >= 0: |
| 339 # The object does not support the item interface. | |
| 340 # Try to re-raise the original attribute error. | |
| 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 | 343 raise |
|
2351
97fae0466d97
more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents:
2349
diff
changeset
|
344 done.append((name, o)) |
| 1049 | 345 object = o |
| 346 | |
| 347 return object |
