我使用的系统允许用户将Python布尔表达式指定为字符串(在配置文件中),系统获取字符串,将其转换为Python AST对象,然后基于输入数据计算表达式。
在某些情况下,布尔表达式可能会导致错误条件(例如输入数据的条目数不正确)。要求是如果用户将布尔表达式 Package 在fail_on_error(...)
中,则会捕获异常并转换为False
(例如):
assert test('fail_on_error(True)') == True
assert test('fail_on_error(False)') == False
assert test('fail_on_error(list()[0])') == False # index out of range
这可以使用正则表达式来完成,解析表达式字符串,但是我更愿意用Python的ast
模块来“正确地”完成,不幸的是我遇到了问题。
密码
class ReplaceWithTry(ast.NodeTransformer):
def visit_Call(self, node):
if node.func.id != 'fail_on_error':
return node
# Get (first) argument to 'fail_on_error' and return its evaluated expression
return_expr = ast.Return(value=node.args[0])
except_handler = ast.ExceptHandler(type=None,
name=None,
body=ast.Return(value=ast.NameConstant(value=False))])
return ast.Try(body=[return_expr],
handlers=[except_handler],
orelse=[],
finalbody=[])
def test(expr_str):
syntax_tree = ast.parse(expr_str, '<string>', 'eval')
new_tree = ast.fix_missing_locations(ReplaceWithTry().visit(syntax_tree))
ast_obj = compile(new_tree, '<string>', 'eval')
return eval(ast_obj)
错误
我收到以下错误:
knoepfel$ python replace_with_try.py
Traceback (most recent call last):
File "replace_with_try.py", line 24, in <module>
assert test('fail_on_error(True)')
File "replace_with_try.py", line 21, in test
ast_obj = compile(new_tree, '<string>', 'eval')
TypeError: expected some sort of expr, but got <ast.Try object at 0x103da33a0>
显然我漏掉了什么。有什么想法吗?
1条答案
按热度按时间lmyy7pcs1#
这是一个很老的问题,但我想这是可行的
以及