eval() interprets a string as code. The reason why so many people have warned you about using this is because a user can use this as an option to run code on the computer. If you have eval(input()) and os imported, a person could type into input() os.system('rm -R *') which would delete all your files in your home directory. (Assuming you have a unix system). Using eval() is a security hole. If you need to convert strings to other formats, try to use things that do that, like int().
As described in the documentation, eval() also has globals and locals keyword arguments which can be used to limit the functions that are available through the eval function. For example, if you load up a fresh Python interpreter the locals() and globals() will be the same and look something like this:
Now we have the cpu_count function available while still blocking everything we do not want. In my opinion, this is super powerful and clearly from the scope of the other answers, not a common implementation. There are numerous uses for something like this and as long as it is handled correctly, I personally feel eval can be safely used to great value.
Something else that is cool about these kwargs is that you can start to use shorthand for your code. Let's say you use eval as part of a pipeline to execute some imported text. The text doesn't need to have exact code, it can follow some template file format, and still execute anything you'd like. For example:
In Python 2.x input(...) is equivalent to eval(raw_input(...)), in Python 3.x raw_input was renamed input, which I suspect lead to your confusion (you were probably looking at the documentation for input in Python 2.x). Additionally, eval(input(...)) would work fine in Python 3.x, but would raise a TypeError in Python 2.
One reason you might be confused is because the code you cited involves a level of indirection. The inner function call (input) gets executed first so the user sees the "blah" prompt. Let's imagine they respond with "1 + 1" (quotes added for clarity, don't type them when running your program), the input function returns that string, which is then passed to the outer function (eval) which interprets the string and returns the result (2).
Safely evaluate an expression node or a string containing a Python literal or container display. The string or node provided may only consist of the following Python literal structures: strings, bytes, numbers, tuples, lists, dicts, sets, booleans, and None.
This can be used for safely evaluating strings containing Python values from untrusted sources without the need to parse the values oneself. It is not capable of evaluating arbitrarily complex expressions, for example involving operators or indexing.
If you're satisfied with plain expressions using elementary-type literals only, use ast.literal_eval -- that's what it's for! For anything fancier, I recommend a parsing package, such as ply if you're familiar and comfortable with the classic lexx/yacc approach, or pyparsing for a possibly more Pythonic approach.
overall, "eval" security, in any language, is a big issue. SQL injection attacks are just an example of such a security hole. Perl Safe has had security bugs over the years - most recent one I remember, it was safe, except for destructors on objects returned from the safe eval.
You can use the built-in Python eval() to dynamically evaluate expressions from a string-based or compiled-code-based input. If you pass in a string to eval(), then the function parses it, compiles it to bytecode, and evaluates it as a Python expression. But if you call eval() with a compiled code object, then the function performs just the evaluation step, which is quite convenient if you call eval() several times with the same input.
Note: You can also use exec() to dynamically execute Python code. The main difference between eval() and exec() is that eval() can only execute or evaluate expressions, whereas exec() can execute any piece of Python code.
When you call eval() with a string as an argument, the function returns the value that results from evaluating the input string. By default, eval() has access to global names like x in the above example.
The name expression for the first argument to eval() highlights that the function works only with expressions and not with compound statements. The Python documentation defines expression as follows:
A piece of syntax which can be evaluated to some value. In other words, an expression is an accumulation of expression elements like literals, names, attribute access, operators or function calls which all return a value. In contrast to many other languages, not all language constructs are expressions. There are also statements which cannot be used as expressions, such as while. Assignments are also statements, not expressions. (Source)
Note: A for loop is a compound statement, but the for keyword can also be used in comprehensions, which are considered expressions. You can use eval() to evaluate comprehensions even though they use the for keyword.
All the names passed to globals in a dictionary will be available to eval() at execution time. Check out the following example, which shows how to use a custom dictionary to supply a global namespace to eval():
You can insert names into globals by listing them in your dictionary, and then those names will be available during the evaluation process. For example, if you insert y into globals, then the evaluation of "x + y" in the above example will work as expected:
The mechanism behind globals is quite flexible. You can pass any visible variable (global, local, or nonlocal) to globals. You can also pass custom key-value pairs like "z": 300 in the above example. eval() will treat all of them as global variables.
Like with globals, you can pass any visible variable (global, local, or nonlocal) to locals. You can also pass custom key-value pairs like "x": 100 in the above example. eval() will treat all of them as local variables.
Now, you may be thinking, why should I use eval() instead of using the Boolean expression directly? Well, suppose you need to implement a conditional statement, but you want to change the condition on the fly:
Inside func(), you use eval() to evaluate the supplied condition and return either a + b or a - b according to the result of the evaluation. You use just a few different conditions in the above example, but you could use any number of others provided that you stick with the names a and b that you defined in func().
When you use eval() to evaluate math expressions, you can pass in expressions of any kind or complexity. eval() will parse them, evaluate them and, if everything is okay, give you the expected result.
For this reason, good programming practices generally recommend against using eval(). But if you choose to use the function anyway, then the rule of thumb is to never ever use it with untrusted input. The tricky part of this rule is figuring out which kinds of input you can trust.
In eval_expression(), you implement all of the steps you saw before. This function restricts the names that you can use with eval() to only those names in the dictionary allowed_names. To do this, the function uses .co_names, which is an attribute of a code object that returns a tuple containing the names in the code object.
In Python 3.x, the built-in input() reads the user input at the command line, converts it to a string, strips the trailing newline, and returns the result to the caller. Since the result of input() is a string, you can feed it to eval() and evaluate it as a Python expression:
In line 26, you define evaluate(). This function takes the string expression as an argument and returns a float that represents the result of evaluating the string as a math expression.
In line 36, you perform the actual evaluation of the math expression. Notice that you pass custom dictionaries to globals and locals as good practice recommends. ALLOWED_NAMES holds the functions and constants defined in math.
The first rule of code clarity is that each line of your code should be easy to understand by looking only at the lines near it. This is why goto and global variables are discouraged. exec and eval make it easy to break this rule badly.
You can, with proper escaping and filtering, use exec and eval safely. But the kind of coder who goes straight for exec/eval to solve a problem (because they don't understand the other facilities the language makes available) isn't the kind of coder that's going to be able to get that processing right; it's going to be someone who doesn't understand string processing and just blindly concatenates substrings, resulting in fragile insecure code.
It's the Lure Of Strings. Throwing string segments around looks easy and fools naïve coders into thinking they understand what they're doing. But experience shows the results are almost always wrong in some corner (or not-so-corner) case, often with potential security implications. This is why we say eval is evil. This is why we say regex-for-HTML is evil. This is why we push SQL parameterisation. Yes, you can get all these things right with manual string processing... but unless you already understand why we say those things, chances are you won't.
Security aside, eval and exec are often marked as undesirable because of the complexity they induce. When you see a eval call you often don't know what's really going on behind it, because it acts on data that's usually in a variable. This makes code harder to read.
eval() and exec() can promote lazy programming. More importantly it indicates the code being executed may not have been written at design time therefore not tested. In other words, how do you test dynamically generated code? Especially across browsers.
In contrast to what most answers are saying here, exec is actually part of the recipe for building super-complete decorators in Python, as you can duplicate everything about the decorated function exactly, producing the same signature for the purposes of documentation and such. It's key to the functionality of the widely used decorator module ( ). Other cases where exec/eval are essential is when constructing any kind of "interpreted Python" type of application, such as a Python-parsed template language (like Mako or Jinja).
760c119bf3