eval()
Evaluate a Python expression from a string. Only use on TRUSTED input — never on user data.
Common call
eval("1 + 2")
Returns
the value of the expression
Replaces
nothing — usually you should NOT reach for eval
Watch out
evaluates ARBITRARY Python — never call on untrusted input; prefer ast.literal_eval
eval(sourcesource — A string containing a Python EXPRESSION. Not a statement — no assignment, no def / class / import at top level. A compiled code object is also accepted.type: str | code · required, globalsglobals — Optional globals dict for the evaluation. If None, uses the caller's globals. If provided without __builtins__, Python inserts one automatically.type: dict · default: None=None, localslocals — Optional locals dict. Defaults to the globals dict.type: dict · default: None=None)
→ Any
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| source | str | code | yes | A string containing a Python EXPRESSION. Not a statement — no assignment, no def / class / import at top level. A compiled code object is also accepted. |
| globals | dict | no (None) | Optional globals dict for the evaluation. If None, uses the caller's globals. If provided without __builtins__, Python inserts one automatically. |
| locals | dict | no (None) | Optional locals dict. Defaults to the globals dict. |
Return value
Any — The result of evaluating the given Python EXPRESSION string. Only an expression — not a statement (no assignment, no def, no import at top level). Uses the caller's globals and locals unless explicit dicts are passed.
Common patterns
For LITERAL data — use ast.literal_eval, not eval
When you need to parse a Python-shaped literal from a string.
import ast data = ast.literal_eval("[1, 2, 3]") # safe
For JSON data — use json.loads
JSON is a standard format with a dedicated parser.
import json data = json.loads('{"a": 1}')
For math expressions from users
Use a real math parser (sympy, or a small pratt parser). Never eval.
import sympy sympy.sympify("1 + 2 * x") # safe symbolic eval
Trusted expression at runtime
If the source is definitely trusted (your own code), eval is OK — but consider a lambda instead.
formula = "x + y" result = eval(formula, {"x": 3, "y": 4})
Examples
1. Arithmetic
eval("1 + 2 * 3")
Returns
72. String call
eval("'hi'.upper()")
Returns
"HI"3. Comprehension
eval("[x * 2 for x in range(3)]")
Returns
[0, 2, 4]4. Uses caller scope
x = 10
eval("x + 1")
Returns
115. Custom scope
eval("a + b", {"a": 3, "b": 4})
Returns
76. Statements fail
eval("x = 1")
Returns
SyntaxError: invalid syntaxPitfalls
1. DANGEROUS on untrusted input — arbitrary code execution
The single most important warning. eval on user input is a remote code execution vulnerability. Even if you restrict globals, __builtins__ leaks give access to import, os, and the filesystem.
Untrusted eval
eval(request.form["math"])
attacker can run ANY Python
ast.literal_eval
import ast ast.literal_eval(request.form["math"])
only literal data allowed
2. Restricting globals is NOT sufficient sandboxing
Passing an empty globals={} does not prevent access to __builtins__ tricks. A determined attacker can reach the class hierarchy via `().__class__.__bases__[0].__subclasses__()` and find dangerous classes. There is no reliable way to sandbox eval in pure Python.
False security
eval(untrusted, {})
still exploitable
Do not eval untrusted
use a real parser
3. STATEMENTS fail — use exec for those
eval takes an expression. `x = 1` is a statement, not an expression. Assignment expressions (walrus) work as they are expressions: `eval("(x := 1)")`.
Statement
eval("x = 1")
SyntaxError
exec for statements
exec("x = 1")
x is now 1
4. Silent scope pollution
Without explicit globals / locals, eval reads and writes the CALLER'S scope. Even if you did not intend to mutate anything, an eval'd expression can call methods with side effects on your variables.
Reads caller scope
secret = "hunter2" eval("open(secret)")
reads secret
Explicit scope
eval(source, {"__builtins__": None}, {})
still risky, but bounded
When to use
Use it
- Never with untrusted input
- Trusted expressions from your own code (rare — a lambda is usually cleaner)
- REPL-like tools where you WANT arbitrary Python (Jupyter, ipython)
- Extension of a config format that intentionally embeds Python
Reach for something else
- Any input from a user, a network, or a file → ast.literal_eval / json / a real parser
- Math from user input → sympy or a pratt parser
- Serialization → json / pickle / dataclasses
- Dynamic dispatch → a dict of functions
Notes
Complexity
Compile + execution — variable
Return
The expression's value
CPython impl
Python/bltinmodule.c :: builtin_eval — compiles and runs
Memory
Allocates code objects and result
Thread-safe
Depends entirely on the evaluated expression
FAQ
Unsafe on any input you did not fully control. For your own code, it works — but a lambda, a dispatch dict, or a compiled function is almost always clearer and safer. The rule of thumb: if you can avoid eval, you should.
History
1.0
eval() has been a builtin since Python 1.0.
3.0
Python 2 input() removed — it used to call eval on the typed line (security disaster).