用 Try 节点替换 Python Call AST 节点

问题描述

我使用的系统允许用户将 Python 布尔表达式指定为字符串(在配置文件中)。系统获取字符串,将其转换为 Python AST 对象,然后根据输入数据评估表达式。

有时布尔表达式可能会导致错误情况(例如,输入数据的条目数不正确)。要求是,如果用户将布尔表达式包装在 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,'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,'eval')
TypeError: expected some sort of expr,but got <ast.Try object at 0x103da33a0>

显然我错过了一些东西。有什么想法吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)