[ZPT] CVS: Products/PageTemplates - Expressions.py:1.21 PageTemplate.py:1.15 PageTemplateFile.py:1.4 TALES.py:1.22 ZopePageTemplate.py:1.19
Evan Simpson
evan@zope.com
Thu, 11 Oct 2001 13:07:28 -0400
Update of /cvs-repository/Products/PageTemplates
In directory cvs.zope.org:/tmp/cvs-serv25400
Modified Files:
Expressions.py PageTemplate.py PageTemplateFile.py TALES.py
ZopePageTemplate.py
Log Message:
Improve error reporting.
=== Products/PageTemplates/Expressions.py 1.20 => 1.21 ===
reg('python', PythonExpr)
reg('not', NotExpr)
+ reg('defer', DeferExpr)
if sys.modules.has_key('Zope'):
import AccessControl
@@ -194,10 +195,14 @@
ob = econtext.contexts
else:
ob = vars[base]
+ if isinstance(ob, DeferWrapper):
+ ob = ob()
if path:
ob = restrictedTraverse(ob, path, securityManager)
exists = 1
break
+ except Undefined, e:
+ ob = e
except (AttributeError, KeyError, TypeError, IndexError,
'Unauthorized'), e:
ob = Undefined(self._s, sys.exc_info())
@@ -214,10 +219,10 @@
return self._eval(econtext, getSecurityManager())
def __str__(self):
- return '%s expression "%s"' % (self._name, self._s)
+ return '%s expression %s' % (self._name, `self._s`)
def __repr__(self):
- return '<PathExpr %s:%s>' % (self._name, self._s)
+ return '%s:%s' % (self._name, `self._s`)
_interp = re.compile(r'\$(%(n)s)|\${(%(n)s(?:/%(n)s)*)}' % {'n': NAME_RE})
@@ -242,8 +247,7 @@
m = _interp.search(exp)
if '$' in exp:
raise CompilerError, (
- '$ must be doubled or followed by a variable name '
- 'in string expression "%s"' % expr)
+ '$ must be doubled or followed by a simple path')
parts.append(exp)
expr = join(parts, '')
self._expr = expr
@@ -261,7 +265,7 @@
return 'string expression %s' % `self._s`
def __repr__(self):
- return '<StringExpr %s>' % `self._s`
+ return 'string:%s' % `self._s`
class NotExpr:
def __init__(self, name, expr, compiler):
@@ -272,7 +276,29 @@
return not econtext.evaluateBoolean(self._c)
def __repr__(self):
- return '<NotExpr %s>' % `self._s`
+ return 'not:%s' % `self._s`
+
+class DeferWrapper:
+ def __init__(self, expr, econtext):
+ self._expr = expr
+ self._econtext = econtext
+
+ def __str__(self):
+ return str(self())
+
+ def __call__(self):
+ return self._expr(self._econtext)
+
+class DeferExpr:
+ def __init__(self, name, expr, compiler):
+ self._s = expr = lstrip(expr)
+ self._c = compiler.compile(expr)
+
+ def __call__(self, econtext):
+ return DeferWrapper(self._c, econtext)
+
+ def __repr__(self):
+ return 'defer:%s' % `self._s`
def restrictedTraverse(self, path, securityManager,
=== Products/PageTemplates/PageTemplate.py 1.14 => 1.15 ===
expand = 1
_v_errors = ()
+ _v_warnings = ()
_text = ''
_error_start = '<!-- Page Template Diagnostics'
@@ -162,7 +163,16 @@
return self.pt_render(extra_context={'options': kwargs})
def pt_errors(self):
- return self._v_errors
+ err = self._v_errors
+ if err:
+ return err
+ try:
+ self.pt_render(source=1)
+ except:
+ return ('Macro expansion failed', '%s: %s' % sys.exc_info()[:2])
+
+ def pt_warnings(self):
+ return self._v_warnings
def write(self, text):
assert type(text) is type('')
@@ -209,6 +219,7 @@
except:
self._v_errors = ["Compilation failed",
"%s: %s" % sys.exc_info()[:2]]
+ self._v_warnings = parser.getWarnings()
def html(self):
return self.content_type == 'text/html'
=== Products/PageTemplates/PageTemplateFile.py 1.3 => 1.4 ===
# Execute the template in a new security context.
security=getSecurityManager()
+ bound_names['user'] = security.getUser()
security.addContext(self)
try:
return self.pt_render(extra_context=bound_names)
=== Products/PageTemplates/TALES.py 1.21 => 1.22 ===
class TALESError(Exception):
__allow_access_to_unprotected_subobjects__ = 1
- def __init__(self, expression, info=(None, None, None)):
+ def __init__(self, expression, info=(None, None, None),
+ position=(None, None)):
self.type, self.value, self.traceback = info
self.expression = expression
+ self.setPosition(position)
+ def setPosition(self, position):
+ self.lineno = position[0]
+ self.offset = position[1]
def __str__(self):
- if self.type is not None:
- return '%s on %s in "%s"' % (self.type, self.value,
- self.expression)
- return self.expression
+ if self.type is None:
+ s = self.expression
+ else:
+ s = '%s on %s in %s' % (self.type, self.value,
+ `self.expression`)
+ if self.lineno is not None:
+ s = "%s, at line %d" % (s, self.lineno)
+ if self.offset is not None:
+ s = "%s, column %d" % (s, self.offset + 1)
+ return s
def __nonzero__(self):
return 0
class Undefined(TALESError):
'''Exception raised on traversal of an undefined path'''
def __str__(self):
- if self.type is not None:
- return '"%s" not found in "%s"' % (self.value,
- self.expression)
- return self.expression
+ if self.type is None:
+ s = self.expression
+ else:
+ s = '%s not found in %s' % (self.value,
+ `self.expression`)
+ if self.lineno is not None:
+ s = "%s, at line %d" % (s, self.lineno)
+ if self.offset is not None:
+ s = "%s, column %d" % (s, self.offset + 1)
+ return s
class RegistrationError(Exception):
'''TALES Type Registration Error'''
@@ -221,6 +238,8 @@
kwcontexts = contexts
return Context(self, kwcontexts)
+ def getCompilerError(self):
+ return CompilerError
class Context:
'''Expression Context
@@ -231,6 +250,7 @@
_context_class = SafeMapping
_nocatch = TALESError
+ position = (None, None)
def __init__(self, engine, contexts):
self._engine = engine
@@ -297,10 +317,14 @@
if hasattr(v, 'traceback'):
raise v, None, v.traceback
raise v
+ except TALESError, err:
+ err.setPosition(self.position)
+ raise err, None, sys.exc_info()[2]
except self._nocatch:
raise
except:
- raise TALESError, (`expression`, sys.exc_info()), sys.exc_info()[2]
+ raise TALESError, (`expression`, sys.exc_info(),
+ self.position), sys.exc_info()[2]
else:
return v
@@ -329,6 +353,9 @@
def getDefault(self):
return Default
+
+ def setPosition(self, position):
+ self.position = position
class SimpleExpr:
'''Simple example of an expression type handler'''
=== Products/PageTemplates/ZopePageTemplate.py 1.18 => 1.19 ===
'pt_editForm', 'manage_main', 'read',
'ZScriptHTML_tryForm', 'PrincipiaSearchSource',
- 'document_src')
+ 'document_src', 'source.html', 'source.xml')
security.declareProtected('Change Page Templates',
'pt_editAction', 'pt_setTitle', 'pt_edit',
@@ -310,6 +310,8 @@
if RESPONSE is not None:
RESPONSE.setHeader('Content-Type', self.content_type)
+ if REQUEST.get('raw'):
+ return self._text
return self.read()
def __setstate__(self, state):