如何查找/检测Python AST中是否使用了内置函数? [英] How to find/detect if a build-in function is used in Python AST?

查看:167
本文介绍了如何查找/检测Python AST中是否使用了内置函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目标是检测某些代码中是否使用了诸如eval()之类的内置函数.

The goal is to detect if a builtin function such as eval() is used in some code.

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作为输出被打印.

The function name foo is printed as the output.

我知道内建函数没有构造函数.它们在type模块中.因此,一种方法是在isinstance调用中使用types.FunctionType.

I know that Builtin functions don't have constructors. They are in the type Module. So 1 approach would be using types.FunctionType in an isinstance call.

但是由于我使用的是AST节点.它们不能转换回代码.我必须检查每个节点是否为types.FunctionType:

But since I'm using AST nodes. They cannot be transformed back into code. I have to check for each node if they are types.FunctionType:

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

我遇到了这些错误:

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

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

How should I correctly identify if a specific Buildin Function is used in code? Thanks!

推荐答案

在代码中编写eval(whatever)时,将通过普通的全局变量查找来查找eval.您应该寻找一个ast.Name节点,该节点代表变量名eval的使用:

When you write eval(whatever) in your code, eval is looked up by an ordinary global variable lookup. You should look for an ast.Name node representing a use of the variable name eval:

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

由于您有一个实际的函数对象,而不仅仅是源代码,因此,与仅拥有函数源的情况相比,您还可以检查以更可靠的方式遮盖内置变量的变量:

Since you have an actual function object, not just the source code, you can also check for variables that shadow the built-in in a slightly more reliable manner than if you just had the function's source:

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.

这将不会捕获在检查后添加的全局变量,并且不会对使用其他名称(例如,x = eval; x('whatever'))访问内置对象进行任何操作.值得吗?

This won't catch globals added after the check, and it won't do anything about accesses to the built-in by a different name (for example, x = eval; x('whatever')). Whether it's worthwhile is up to you.

这篇关于如何查找/检测Python AST中是否使用了内置函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆