As some of you have used eval and exec in python as a handy quick-and-dirty way to get the dynamic source code, then munge it a little, then execute it. The functionality of ‘eval’ is its ability to evaluate a string as though it were an expression and returns a result. In Python, it can also be a structured representation of code such as abstract syntax tree (like Lisp forms). Its key usages are:
- Evaluating a mathematical expression
- Compiler bootstrapping
- Scripting (dynamic code)
- Language tutors
x = 1 eval('x + 1') # returns 2 eval ('x') # returns 1 # The most general form for evaluating statements is using code objects x = 1 y = 2 eval(compile("print ('x+y=',x+y)", "compile-sample.py", "single")) # returns x + y = 3
However, there is a big safety flaw while using ‘eval’ command which evaluates the code in the expression without considering whether it’s safe or not. See a good article about ‘The danger of eval”. A good example can be:
eval(input("__import__('os').system('rm -rf /root/important_data')"))
The cure for this is to use $ast.literal_eval$ which raise an exception if the input isn’t a valid Python datatype, so the code won’t be executed if it is not safe.
The rule of thumb is to use ast.literal_eval whenever you need eval. But there are some notable differences: ast.literal_eval won’t work for bitwise operators. For example:
ast.literal_eval("1 & 1") # raise an error eval("1 & 1") # will return 1
ast.literal_eval() only considers a small subset of Python’s syntax to be valid:
The string or node provided may only consist of the following Python literal structures: strings, numbers, tuples, lists, dicts, booleans, and None.