如何查找/检测Python AST中是否使用了内置函数? [英] How to find/detect if a build-in function is used in 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屋!