from opcode import HAVE_ARGUMENT, opmap, opname
from types import CodeType
import logging
-import os
__all__ = ['test_expr', 'safe_eval', 'const_eval']
_CONST_OPCODES = set(opmap[x] for x in [
'POP_TOP', 'ROT_TWO', 'ROT_THREE', 'ROT_FOUR', 'DUP_TOP', 'DUP_TOPX',
'POP_BLOCK','SETUP_LOOP', 'BUILD_LIST', 'BUILD_MAP', 'BUILD_TUPLE',
- 'LOAD_CONST', 'RETURN_VALUE', 'STORE_SUBSCR'] if x in opmap)
+ 'LOAD_CONST', 'RETURN_VALUE', 'STORE_SUBSCR', 'STORE_MAP'] if x in opmap)
_EXPR_OPCODES = _CONST_OPCODES.union(set(opmap[x] for x in [
'UNARY_POSITIVE', 'UNARY_NEGATIVE', 'UNARY_NOT',
] if x in opmap))
_SAFE_OPCODES = _EXPR_OPCODES.union(set(opmap[x] for x in [
- 'STORE_MAP', 'LOAD_NAME', 'CALL_FUNCTION', 'COMPARE_OP', 'LOAD_ATTR',
+ 'LOAD_NAME', 'CALL_FUNCTION', 'COMPARE_OP', 'LOAD_ATTR',
'STORE_NAME', 'GET_ITER', 'FOR_ITER', 'LIST_APPEND', 'DELETE_NAME',
'JUMP_FORWARD', 'JUMP_IF_TRUE', 'JUMP_IF_FALSE', 'JUMP_ABSOLUTE',
'MAKE_FUNCTION', 'SLICE+0', 'SLICE+1', 'SLICE+2', 'SLICE+3',
expr = expr.strip()
code_obj = compile(expr, "", mode)
except (SyntaxError, TypeError):
- _logger.debug('Invalid eval expression', exc_info=True)
raise
- except Exception:
- _logger.debug('Disallowed or invalid eval expression', exc_info=True)
- raise ValueError("%s is not a valid expression" % expr)
+ except Exception, e:
+ import sys
+ exc_info = sys.exc_info()
+ raise ValueError, '"%s" while compiling\n%s' % (str(e), expr), exc_info[2]
for code in _get_opcodes(code_obj):
if code not in allowed_codes:
raise ValueError("opcode %s not allowed (%r)" % (opname[code], expr))
'set' : set
}
)
- try:
- return eval(test_expr(expr, _SAFE_OPCODES, mode=mode), globals_dict, locals_dict)
- except Exception:
- _logger.exception('Cannot eval %r', expr)
- raise
+ c = test_expr(expr, _SAFE_OPCODES, mode=mode)
+ return eval(c, globals_dict, locals_dict)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: