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!
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.