How to compile text as a function using AST?
abstract-syntax-tree, exec, python
Solution
AST is a much safer choice when evaluating untrusted code, that could contain malicious instructions, `eval` or `exec` can execute any expression, while AST on the other hand, allows you to parse and validate the expression yourself, or execute a limited expression using `ast.literal_eval`, sort of like a sandbox, which allows only strings, lists, numbers and a few other things. This is just a simple example:
import ast
a = ast.literal_eval("[1,2,3,4]") //evaluate an expression safely.
Another example that parses a string into an AST:
import ast
source = '2 + 2'
node = ast.parse(source, mode='eval')
ast.dump(node)
This prints:
Expression(body=BinOp(left=Num(n=2), op=Add(), right=Num(n=2)))
There's a very good tutorial here and also the documentation
Problem
I need to compile an input string (from a database) as a function and run it. This is the method I currently use: Say I already have this function defined: ``` def foo(): print "Yo foo! I am a function!" ``` And the string I read in from the database says I should call this function: ``` string_from_db = "foo()" ``` I then form a function (whose name I can control) which returns the function I read in from the database: ``` my_func_string = "def doTheFunc():\n\t return " + string_from_db ``` Now I compile the string, and set it to a function name I use later for processing: ``` exec my_func_string processor = doTheFunc ``` I can call it later by running `processor()` which exclaims: `Yo foo! I am a function!` My Question: Above this piece of code there is a comment (left by a long lost developer): ``` ############################################################### # The following method for getting a function out of the text # # in the database could potentially be replaced by using # # Python's ast module to obtain an abstract syntax tree and # # put it inside of a function node # ############################################################### ``` I'd like to know more about this "potential replacement." I have taken a look at AST, but I am very confused on how it can help me do what I am already doing with the code above. - How can I accomplish the same thing using AST? Or where can AST help me in this process? - Is the implementation using AST better, and why?