问题
The goal is to detect if a builtin function such as eval()
is used in some code.
def foo(a):
eval('a = 2')
I have tried the following approach:
ex_ast = ast.parse(inspect.getsource(foo))
for node in ast.walk(ex_ast):
if isinstance(node, ast.FunctionDef):
print(node.name)
The function name foo
is printed as the output.
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.
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)
I got these errors:
AttributeError: module 'ast' has no attribute 'FunctionType'
How should I correctly identify if a specific Buildin Function is used in code? Thanks!
回答1:
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.
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.
来源:https://stackoverflow.com/questions/37217823/how-to-find-detect-if-a-build-in-function-is-used-in-python-ast