Mercurial > p > roundup > code
annotate roundup/cgi/PageTemplates/Expressions.py @ 3896:fca0365521fc
ignore client shutdown exceptions when sending responses
patch from Ulrik Miaelsson
If the user clicks the stop button, or click another link before
the previous has finished loading, or something similar an IOError
exception will be raised which results in the admin being sent an
email.
This can understandably be pretty annoying if your users are
doing that on a regular basis. So we'll trap that exception
and ignore it.
| author | Justus Pendleton <jpend@users.sourceforge.net> |
|---|---|
| date | Tue, 11 Sep 2007 21:30:14 +0000 |
| parents | 5f9e00836006 |
| children | 445e1bc8b1df |
| 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 |
|
2663
5f9e00836006
update comment
Richard Jones <richard@users.sourceforge.net>
parents:
2351
diff
changeset
|
25 __version__='$Revision: 1.12 $'[11:-2] |
| 1049 | 26 |
| 27 import re, sys | |
| 28 from TALES import Engine, CompilerError, _valid_name, NAME_RE, \ | |
| 29 Undefined, Default, _parse_expr | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
30 |
| 1049 | 31 |
| 32 _engine = None | |
| 33 def getEngine(): | |
| 34 global _engine | |
| 35 if _engine is None: | |
| 36 from PathIterator import Iterator | |
| 37 _engine = Engine(Iterator) | |
| 38 installHandlers(_engine) | |
| 39 return _engine | |
| 40 | |
| 41 def installHandlers(engine): | |
| 42 reg = engine.registerType | |
| 43 pe = PathExpr | |
| 44 for pt in ('standard', 'path', 'exists', 'nocall'): | |
| 45 reg(pt, pe) | |
| 46 reg('string', StringExpr) | |
| 47 reg('python', PythonExpr) | |
| 48 reg('not', NotExpr) | |
| 49 reg('defer', DeferExpr) | |
| 50 | |
| 51 from PythonExpr import getSecurityManager, PythonExpr | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
52 guarded_getattr = getattr |
| 1049 | 53 try: |
| 54 from zExceptions import Unauthorized | |
| 55 except ImportError: | |
| 56 Unauthorized = "Unauthorized" | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
57 |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
58 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
|
59 if real_validate(orig, inst, name, v): |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
60 return 1 |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
61 raise Unauthorized, name |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
62 |
| 1049 | 63 def call_with_ns(f, ns, arg=1): |
| 64 if arg==2: | |
| 65 return f(None, ns) | |
| 66 else: | |
| 67 return f(ns) | |
| 68 | |
| 69 class _SecureModuleImporter: | |
| 70 """Simple version of the importer for use with trusted code.""" | |
| 71 __allow_access_to_unprotected_subobjects__ = 1 | |
| 72 def __getitem__(self, module): | |
| 73 __import__(module) | |
| 74 return sys.modules[module] | |
| 75 | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
76 SecureModuleImporter = _SecureModuleImporter() |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
77 |
| 1049 | 78 Undefs = (Undefined, AttributeError, KeyError, |
| 79 TypeError, IndexError, Unauthorized) | |
| 80 | |
| 81 def render(ob, ns): | |
| 82 """ | |
| 83 Calls the object, possibly a document template, or just returns it if | |
| 84 not callable. (From DT_Util.py) | |
| 85 """ | |
| 86 if hasattr(ob, '__render_with_namespace__'): | |
| 87 ob = call_with_ns(ob.__render_with_namespace__, ns) | |
| 88 else: | |
| 89 base = ob | |
| 90 if callable(base): | |
| 91 try: | |
| 92 if getattr(base, 'isDocTemp', 0): | |
| 93 ob = call_with_ns(ob, ns, 2) | |
| 94 else: | |
| 95 ob = ob() | |
| 96 except AttributeError, n: | |
| 97 if str(n) != '__call__': | |
| 98 raise | |
| 99 return ob | |
| 100 | |
| 101 class SubPathExpr: | |
| 102 def __init__(self, path): | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
103 self._path = path = path.strip().split('/') |
| 1049 | 104 self._base = base = path.pop(0) |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
105 if base and not _valid_name(base): |
| 1049 | 106 raise CompilerError, 'Invalid variable name "%s"' % base |
| 107 # Parse path | |
| 108 self._dp = dp = [] | |
| 109 for i in range(len(path)): | |
| 110 e = path[i] | |
| 111 if e[:1] == '?' and _valid_name(e[1:]): | |
| 112 dp.append((i, e[1:])) | |
| 113 dp.reverse() | |
| 114 | |
| 115 def _eval(self, econtext, | |
| 116 list=list, isinstance=isinstance, StringType=type('')): | |
| 117 vars = econtext.vars | |
| 118 path = self._path | |
| 119 if self._dp: | |
| 120 path = list(path) # Copy! | |
| 121 for i, varname in self._dp: | |
| 122 val = vars[varname] | |
| 123 if isinstance(val, StringType): | |
| 124 path[i] = val | |
| 125 else: | |
| 126 # If the value isn't a string, assume it's a sequence | |
| 127 # of path names. | |
| 128 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
|
129 base = self._base |
|
1136
7e193bbda38e
added generic item editing
Richard Jones <richard@users.sourceforge.net>
parents:
1101
diff
changeset
|
130 __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
|
131 if base == 'CONTEXTS' or not base: |
| 1049 | 132 ob = econtext.contexts |
| 133 else: | |
| 134 ob = vars[base] | |
| 135 if isinstance(ob, DeferWrapper): | |
| 136 ob = ob() | |
| 137 if path: | |
| 138 ob = restrictedTraverse(ob, path, getSecurityManager()) | |
| 139 return ob | |
| 140 | |
| 141 class PathExpr: | |
| 142 def __init__(self, name, expr, engine): | |
| 143 self._s = expr | |
| 144 self._name = name | |
|
1233
69bf0d381fd7
Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents:
1181
diff
changeset
|
145 self._hybrid = 0 |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
146 paths = expr.split('|') |
| 1049 | 147 self._subexprs = [] |
| 148 add = self._subexprs.append | |
| 149 for i in range(len(paths)): | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
150 path = paths[i].lstrip() |
| 1049 | 151 if _parse_expr(path): |
| 152 # This part is the start of another expression type, | |
| 153 # 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
|
154 add(engine.compile(('|'.join(paths[i:]).lstrip()))) |
|
1233
69bf0d381fd7
Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents:
1181
diff
changeset
|
155 self._hybrid = 1 |
| 1049 | 156 break |
| 157 add(SubPathExpr(path)._eval) | |
| 158 | |
| 159 def _exists(self, econtext): | |
| 160 for expr in self._subexprs: | |
| 161 try: | |
| 162 expr(econtext) | |
| 163 except Undefs: | |
| 164 pass | |
| 165 else: | |
| 166 return 1 | |
| 167 return 0 | |
| 168 | |
| 169 def _eval(self, econtext, | |
| 170 isinstance=isinstance, StringType=type(''), render=render): | |
| 171 for expr in self._subexprs[:-1]: | |
| 172 # Try all but the last subexpression, skipping undefined ones. | |
| 173 try: | |
| 174 ob = expr(econtext) | |
| 175 except Undefs: | |
| 176 pass | |
| 177 else: | |
| 178 break | |
| 179 else: | |
|
1233
69bf0d381fd7
Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents:
1181
diff
changeset
|
180 # On the last subexpression allow exceptions through, and |
|
69bf0d381fd7
Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents:
1181
diff
changeset
|
181 # don't autocall if the expression was not a subpath. |
| 1049 | 182 ob = self._subexprs[-1](econtext) |
|
1233
69bf0d381fd7
Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents:
1181
diff
changeset
|
183 if self._hybrid: |
|
69bf0d381fd7
Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents:
1181
diff
changeset
|
184 return ob |
| 1049 | 185 |
| 186 if self._name == 'nocall' or isinstance(ob, StringType): | |
| 187 return ob | |
| 188 # Return the rendered object | |
| 189 return render(ob, econtext.vars) | |
| 190 | |
| 191 def __call__(self, econtext): | |
| 192 if self._name == 'exists': | |
| 193 return self._exists(econtext) | |
| 194 return self._eval(econtext) | |
| 195 | |
| 196 def __str__(self): | |
| 197 return '%s expression %s' % (self._name, `self._s`) | |
| 198 | |
| 199 def __repr__(self): | |
| 200 return '%s:%s' % (self._name, `self._s`) | |
| 201 | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
202 |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
203 _interp = re.compile(r'\$(%(n)s)|\${(%(n)s(?:/[^}]*)*)}' % {'n': NAME_RE}) |
| 1049 | 204 |
| 205 class StringExpr: | |
| 206 def __init__(self, name, expr, engine): | |
| 207 self._s = expr | |
| 208 if '%' in expr: | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
209 expr = expr.replace('%', '%%') |
| 1049 | 210 self._vars = vars = [] |
| 211 if '$' in expr: | |
| 212 parts = [] | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
213 for exp in expr.split('$$'): |
| 1049 | 214 if parts: parts.append('$') |
| 215 m = _interp.search(exp) | |
| 216 while m is not None: | |
| 217 parts.append(exp[:m.start()]) | |
| 218 parts.append('%s') | |
| 219 vars.append(PathExpr('path', m.group(1) or m.group(2), | |
| 220 engine)) | |
| 221 exp = exp[m.end():] | |
| 222 m = _interp.search(exp) | |
| 223 if '$' in exp: | |
| 224 raise CompilerError, ( | |
| 225 '$ must be doubled or followed by a simple path') | |
| 226 parts.append(exp) | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
227 expr = ''.join(parts) |
| 1049 | 228 self._expr = expr |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
229 |
| 1049 | 230 def __call__(self, econtext): |
| 231 vvals = [] | |
| 232 for var in self._vars: | |
| 233 v = var(econtext) | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
234 # 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
|
235 ## if isinstance(v, Exception): |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
236 ## raise v |
| 1049 | 237 vvals.append(v) |
| 238 return self._expr % tuple(vvals) | |
| 239 | |
| 240 def __str__(self): | |
| 241 return 'string expression %s' % `self._s` | |
| 242 | |
| 243 def __repr__(self): | |
| 244 return 'string:%s' % `self._s` | |
| 245 | |
| 246 class NotExpr: | |
| 247 def __init__(self, name, expr, compiler): | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
248 self._s = expr = expr.lstrip() |
| 1049 | 249 self._c = compiler.compile(expr) |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
250 |
| 1049 | 251 def __call__(self, econtext): |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
252 # 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
|
253 # 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
|
254 # 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
|
255 return (not econtext.evaluateBoolean(self._c)) and 1 or 0 |
| 1049 | 256 |
| 257 def __repr__(self): | |
| 258 return 'not:%s' % `self._s` | |
| 259 | |
| 260 class DeferWrapper: | |
| 261 def __init__(self, expr, econtext): | |
| 262 self._expr = expr | |
| 263 self._econtext = econtext | |
| 264 | |
| 265 def __str__(self): | |
| 266 return str(self()) | |
| 267 | |
| 268 def __call__(self): | |
| 269 return self._expr(self._econtext) | |
| 270 | |
| 271 class DeferExpr: | |
| 272 def __init__(self, name, expr, compiler): | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
273 self._s = expr = expr.lstrip() |
| 1049 | 274 self._c = compiler.compile(expr) |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
275 |
| 1049 | 276 def __call__(self, econtext): |
| 277 return DeferWrapper(self._c, econtext) | |
| 278 | |
| 279 def __repr__(self): | |
| 280 return 'defer:%s' % `self._s` | |
| 281 | |
|
2351
97fae0466d97
more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents:
2349
diff
changeset
|
282 class TraversalError: |
|
97fae0466d97
more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents:
2349
diff
changeset
|
283 def __init__(self, path, name): |
|
97fae0466d97
more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents:
2349
diff
changeset
|
284 self.path = path |
|
97fae0466d97
more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents:
2349
diff
changeset
|
285 self.name = name |
|
97fae0466d97
more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents:
2349
diff
changeset
|
286 |
|
97fae0466d97
more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents:
2349
diff
changeset
|
287 |
| 1049 | 288 |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
289 def restrictedTraverse(object, path, securityManager, |
| 1049 | 290 get=getattr, has=hasattr, N=None, M=[], |
| 291 TupleType=type(()) ): | |
| 292 | |
| 293 REQUEST = {'path': path} | |
| 294 REQUEST['TraversalRequestNameStack'] = path = path[:] # Copy! | |
| 295 path.reverse() | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
296 validate = securityManager.validate |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
297 __traceback_info__ = REQUEST |
|
2351
97fae0466d97
more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents:
2349
diff
changeset
|
298 done = [] |
| 1049 | 299 while path: |
| 300 name = path.pop() | |
|
2351
97fae0466d97
more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents:
2349
diff
changeset
|
301 __traceback_info__ = TraversalError(done, name) |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
302 |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
303 if isinstance(name, TupleType): |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
304 object = object(*name) |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
305 continue |
| 1049 | 306 |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
307 if not name: |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
308 # Skip directly to item access |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
309 o = object[name] |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
310 # Check access to the item. |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
311 if not validate(object, object, name, o): |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
312 raise Unauthorized, name |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
313 object = o |
|
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
314 continue |
| 1049 | 315 |
| 316 # Try an attribute. | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
317 o = guarded_getattr(object, name, M) |
| 1049 | 318 if o is M: |
| 319 # Try an item. | |
| 320 try: | |
| 321 # XXX maybe in Python 2.2 we can just check whether | |
| 322 # the object has the attribute "__getitem__" | |
| 323 # instead of blindly catching exceptions. | |
| 324 o = object[name] | |
| 325 except AttributeError, exc: | |
| 326 if str(exc).find('__getitem__') >= 0: | |
| 327 # The object does not support the item interface. | |
| 328 # Try to re-raise the original attribute error. | |
| 329 # XXX I think this only happens with | |
| 330 # ExtensionClass instances. | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
331 guarded_getattr(object, name) |
| 1049 | 332 raise |
| 333 except TypeError, exc: | |
| 334 if str(exc).find('unsubscriptable') >= 0: | |
| 335 # The object does not support the item interface. | |
| 336 # Try to re-raise the original attribute error. | |
| 337 # XXX This is sooooo ugly. | |
|
2349
b43efe461b3e
update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents:
2005
diff
changeset
|
338 guarded_getattr(object, name) |
| 1049 | 339 raise |
|
2351
97fae0466d97
more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents:
2349
diff
changeset
|
340 done.append((name, o)) |
| 1049 | 341 object = o |
| 342 | |
| 343 return object |
