如何查找/检测Python AST中是否使用了内置函数?

时间:2016-05-13 19:22:10

标签: python parsing abstract-syntax-tree built-in isinstance

目标是检测某些代码中是否使用了内置函数,例如eval()

def foo(a):
    eval('a = 2')

我尝试了以下方法:

ex_ast = ast.parse(inspect.getsource(foo))

for node in ast.walk(ex_ast):
if isinstance(node, ast.FunctionDef):
    print(node.name)

打印函数名foo作为输出。

我知道内置函数没有构造函数。它们位于type模块中。因此,1种方法将在types.FunctionType调用中使用isinstance

但是因为我使用的是AST节点。它们无法转换回代码。我必须检查每个节点是否为types.FunctionType

for node in ast.walk(ex_ast):
    if isinstance(node, ast.FunctionType):
        print(node.name)

我收到了这些错误:

AttributeError: module 'ast' has no attribute 'FunctionType'

如何正确识别代码中是否使用了特定的Buildin函数?谢谢!

1 个答案:

答案 0 :(得分:1)

当您在代码中编写eval(whatever)时,eval会被普通的全局变量查找查找。您应该查找表示使用变量名ast.Name的<{1}}节点:

eval

由于你有一个实际的函数对象,而不仅仅是源代码,你还可以检查影响内置函数的变量,这种变量比你刚才拥有该函数的源更可靠:

for node in ast.walk(ex_ast):
    if isinstance(node, ast.Name) and node.id == 'eval':
        # Found it.

在检查后添加的全局变量不会被捕获,并且它不会通过其他名称(例如if ('eval' in foo.__code__.co_varnames # local variable or 'eval' in foo.__code__.co_cellvars # local variable used by nested function or 'eval' in foo.__code__.co_freevars # local variable from enclosing function or 'eval' in foo.__globals__): # global variable # Some variable is shadowing the built-in. )对内置访问做任何事情。它是否值得取决于你。