简体   繁体   中英

How to find/detect if a build-in function is used in Python AST?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM