[pod] Improved error handling. [px] More work on PX.
This commit is contained in:
parent
d5296ba321
commit
bfbf9bea82
|
@ -22,9 +22,9 @@ from appy.pod import PodError
|
||||||
from appy.pod.elements import *
|
from appy.pod.elements import *
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
EVAL_ERROR = 'Error while evaluating expression "%s".'
|
EVAL_ERROR = 'Error while evaluating expression "%s". %s'
|
||||||
FROM_EVAL_ERROR = 'Error while evaluating the expression "%s" defined in the ' \
|
FROM_EVAL_ERROR = 'Error while evaluating the expression "%s" defined in the ' \
|
||||||
'"from" part of a statement.'
|
'"from" part of a statement. %s'
|
||||||
WRONG_SEQ_TYPE = 'Expression "%s" is not iterable.'
|
WRONG_SEQ_TYPE = 'Expression "%s" is not iterable.'
|
||||||
TABLE_NOT_ONE_CELL = "The table you wanted to populate with '%s' " \
|
TABLE_NOT_ONE_CELL = "The table you wanted to populate with '%s' " \
|
||||||
"can\'t be dumped with the '-' option because it has " \
|
"can\'t be dumped with the '-' option because it has " \
|
||||||
|
@ -53,8 +53,24 @@ class BufferAction:
|
||||||
# We store the result of evaluation of expr and fromExpr
|
# We store the result of evaluation of expr and fromExpr
|
||||||
self.exprResult = None
|
self.exprResult = None
|
||||||
self.fromExprResult = None
|
self.fromExprResult = None
|
||||||
|
# When an error is encountered, must we raise it or write it into the
|
||||||
|
# buffer?
|
||||||
|
self.raiseErrors = self.buffer.caller() == 'px'
|
||||||
|
|
||||||
|
def getExceptionLine(self, e):
|
||||||
|
'''Gets the line describing exception p_e, containing the pathname of
|
||||||
|
the exception class, the exception's message and line number.'''
|
||||||
|
return '%s.%s: %s' % (e.__module__, e.__class__.__name__, str(e))
|
||||||
|
|
||||||
def writeError(self, errorMessage, dumpTb=True):
|
def writeError(self, errorMessage, dumpTb=True):
|
||||||
|
'''Write the encountered error into the buffer or raise an exception
|
||||||
|
if self.raiseErrors is True.'''
|
||||||
|
if self.raiseErrors:
|
||||||
|
if self.buffer.caller() == 'px':
|
||||||
|
# Add in the error message the line nb where the errors occurs
|
||||||
|
# within the PX.
|
||||||
|
import pdb; pdb.set_trace()
|
||||||
|
raise Exception(errorMessage)
|
||||||
# Empty the buffer
|
# Empty the buffer
|
||||||
self.buffer.__init__(self.buffer.env, self.buffer.parent)
|
self.buffer.__init__(self.buffer.env, self.buffer.parent)
|
||||||
PodError.dump(self.buffer, errorMessage, withinElement=self.elem,
|
PodError.dump(self.buffer, errorMessage, withinElement=self.elem,
|
||||||
|
@ -67,9 +83,9 @@ class BufferAction:
|
||||||
try:
|
try:
|
||||||
res = eval(expr, self.buffer.env.context)
|
res = eval(expr, self.buffer.env.context)
|
||||||
error = False
|
error = False
|
||||||
except:
|
except Exception, e:
|
||||||
res = None
|
res = None
|
||||||
self.writeError(EVAL_ERROR % expr)
|
self.writeError(EVAL_ERROR % (expr, self.getExceptionLine(e)))
|
||||||
error = True
|
error = True
|
||||||
return res, error
|
return res, error
|
||||||
|
|
||||||
|
@ -91,17 +107,14 @@ class BufferAction:
|
||||||
else:
|
else:
|
||||||
# Evaluate fromExpr
|
# Evaluate fromExpr
|
||||||
self.fromExprResult = None
|
self.fromExprResult = None
|
||||||
errorOccurred = False
|
error = False
|
||||||
try:
|
try:
|
||||||
self.fromExprResult= eval(self.fromExpr,self.buffer.env.context)
|
self.fromExprResult= eval(self.fromExpr,self.buffer.env.context)
|
||||||
except PodError, pe:
|
except Exception, e:
|
||||||
self.writeError(FROM_EVAL_ERROR % self.fromExpr + ' ' + str(pe),
|
msg= FROM_EVAL_ERROR % (self.fromExpr, self.getExceptionLine(e))
|
||||||
dumpTb=False)
|
self.writeError(msg, dumpTb=False)
|
||||||
errorOccurred = True
|
error = True
|
||||||
except:
|
if not error:
|
||||||
self.writeError(FROM_EVAL_ERROR % self.fromExpr)
|
|
||||||
errorOccurred = True
|
|
||||||
if not errorOccurred:
|
|
||||||
self.result.write(self.fromExprResult)
|
self.result.write(self.fromExprResult)
|
||||||
|
|
||||||
class IfAction(BufferAction):
|
class IfAction(BufferAction):
|
||||||
|
@ -171,9 +184,8 @@ class ForAction(BufferAction):
|
||||||
context = self.buffer.env.context
|
context = self.buffer.env.context
|
||||||
# Check self.exprResult type
|
# Check self.exprResult type
|
||||||
try:
|
try:
|
||||||
|
# All "iterable" objects are OK.
|
||||||
iter(self.exprResult)
|
iter(self.exprResult)
|
||||||
# All "iterable" objects are OK. Thanks to Bernhard Bender for this
|
|
||||||
# improvement.
|
|
||||||
except TypeError:
|
except TypeError:
|
||||||
self.writeError(WRONG_SEQ_TYPE % self.expr)
|
self.writeError(WRONG_SEQ_TYPE % self.expr)
|
||||||
return
|
return
|
||||||
|
@ -264,31 +276,28 @@ class VariablesAction(BufferAction):
|
||||||
fromExpr)
|
fromExpr)
|
||||||
# Definitions of variables: ~{s_name: s_expr}~
|
# Definitions of variables: ~{s_name: s_expr}~
|
||||||
self.variables = variables
|
self.variables = variables
|
||||||
# Results of executing the variables: ~{s_name: exprResult}~
|
|
||||||
self.results = {}
|
|
||||||
|
|
||||||
def do(self):
|
def do(self):
|
||||||
context = self.buffer.env.context
|
context = self.buffer.env.context
|
||||||
# Evaluate the variables' expressions: because there are several
|
# Evaluate the variables' expressions: because there are several
|
||||||
# expressions, we did not use the standard, single-expression-minded
|
# expressions, we did not use the standard, single-expression-minded
|
||||||
# BufferAction code for evaluating the expression.
|
# BufferAction code for evaluating our expressions.
|
||||||
# Also: remember the names and values of the variables that we will hide
|
# Also: we remember the names and values of the variables that we will
|
||||||
# in the context: after execution of this buffer we will restore those
|
# hide in the context: after execution of this buffer we will restore
|
||||||
# values in the context.
|
# those values.
|
||||||
hidden = None
|
hidden = None
|
||||||
for name, expr in self.variables.iteritems():
|
for name, expr in self.variables.iteritems():
|
||||||
# Evaluate the expression
|
# Evaluate the expression
|
||||||
result, error = self.evaluateExpression(expr)
|
result, error = self.evaluateExpression(expr)
|
||||||
if error: return
|
if error: return
|
||||||
self.results[name] = result
|
|
||||||
# Remember the variable previous value if already in the context
|
# Remember the variable previous value if already in the context
|
||||||
if name in context:
|
if name in context:
|
||||||
if not hidden:
|
if not hidden:
|
||||||
hidden = {name: context[name]}
|
hidden = {name: context[name]}
|
||||||
else:
|
else:
|
||||||
hidden[name] = context[name]
|
hidden[name] = context[name]
|
||||||
# Add our variables to the context
|
# Store the result into the context
|
||||||
context.update(self.results)
|
context[name] = result
|
||||||
# Evaluate the buffer
|
# Evaluate the buffer
|
||||||
self.evaluateBuffer()
|
self.evaluateBuffer()
|
||||||
# Restore hidden variables if any
|
# Restore hidden variables if any
|
||||||
|
|
|
@ -459,8 +459,9 @@ class MemoryBuffer(Buffer):
|
||||||
|
|
||||||
def createPxAction(self, elem, actionType, statement):
|
def createPxAction(self, elem, actionType, statement):
|
||||||
res = 0
|
res = 0
|
||||||
|
statement = statement.strip()
|
||||||
if actionType == 'for':
|
if actionType == 'for':
|
||||||
forRes = MemoryBuffer.forRex.match(statement.strip())
|
forRes = MemoryBuffer.forRex.match(statement)
|
||||||
if not forRes:
|
if not forRes:
|
||||||
raise ParsingError(BAD_FOR_EXPRESSION % statement)
|
raise ParsingError(BAD_FOR_EXPRESSION % statement)
|
||||||
iter, subExpr = forRes.groups()
|
iter, subExpr = forRes.groups()
|
||||||
|
|
|
@ -77,7 +77,7 @@ class Expression(PodElement):
|
||||||
OD = None
|
OD = None
|
||||||
def __init__(self, pyExpr):
|
def __init__(self, pyExpr):
|
||||||
# The Python expression
|
# The Python expression
|
||||||
self.expr = pyExpr
|
self.expr = pyExpr.strip()
|
||||||
# We will store here the expression's true result (before being
|
# We will store here the expression's true result (before being
|
||||||
# converted to a string)
|
# converted to a string)
|
||||||
self.result = None
|
self.result = None
|
||||||
|
|
3627
pod/test/Tests.rtf
3627
pod/test/Tests.rtf
File diff suppressed because it is too large
Load diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -5,8 +5,6 @@ from appy.pod.buffers import MemoryBuffer
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
class PxEnvironment(XmlEnvironment):
|
class PxEnvironment(XmlEnvironment):
|
||||||
'''Environment for the PX parser.'''
|
'''Environment for the PX parser.'''
|
||||||
# PX-specific attributes must not be dumped into the result.
|
|
||||||
undumpableAttrs = ('for', 'if')
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# We try to mimic POD. POD has a root buffer that is a FileBuffer, which
|
# We try to mimic POD. POD has a root buffer that is a FileBuffer, which
|
||||||
|
@ -55,7 +53,6 @@ class PxEnvironment(XmlEnvironment):
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
class PxParser(XmlParser):
|
class PxParser(XmlParser):
|
||||||
'''PX parser that is specific for parsing PX data.'''
|
'''PX parser that is specific for parsing PX data.'''
|
||||||
|
|
||||||
pxAttributes = ('var', 'for', 'if')
|
pxAttributes = ('var', 'for', 'if')
|
||||||
|
|
||||||
def __init__(self, env, caller=None):
|
def __init__(self, env, caller=None):
|
||||||
|
@ -81,7 +78,7 @@ class PxParser(XmlParser):
|
||||||
e.currentBuffer.addElement(elem, elemType='px')
|
e.currentBuffer.addElement(elem, elemType='px')
|
||||||
if elem != 'x':
|
if elem != 'x':
|
||||||
e.currentBuffer.dumpStartElement(elem, attrs,
|
e.currentBuffer.dumpStartElement(elem, attrs,
|
||||||
ignoreAttrs=e.undumpableAttrs)
|
ignoreAttrs=self.pxAttributes)
|
||||||
|
|
||||||
def endElement(self, elem):
|
def endElement(self, elem):
|
||||||
e = self.env
|
e = self.env
|
||||||
|
|
Loading…
Reference in a new issue