Python Python eval(): Execute code from strings — syntax, globals and locals,…
page info
name Goposu datetime⏰ 25-10-11 17:41 hit👁️ 10 comment💬 0text

Python eval(): Evaluate a Python expression from a string
eval()
parses and evaluates a Python expression given as a string (or compiled code object) and returns its result. It can be powerful for dynamic behavior, but it carries significant security risks if used with untrusted input. This guide explains correct usage, scoping via globals
/locals
, safer alternatives, the compile()
function, and practical patterns.
Syntax
eval(expression, globals=None, locals=None)
- expression: A string containing a valid Python expression (not a full statement like
def
,class
, orimport
). - globals: Optional dictionary for the global namespace used during evaluation.
- locals: Optional dictionary for the local namespace used during evaluation.
Quick examples
# Basic arithmeticprint(eval("1 + 2 * 3")) # 7
Using variables via locals
x, y = 10, 3 print(eval("x ** y", {}, {"x": x, "y": y})) # 1000
Accessing functions via globals
ctx = {"max": max, "builtins": {}} print(eval("max(4, 9)", ctx)) # 9
Globals and locals
eval()
resolves names using the provided globals
and locals
dictionaries. If they are omitted, it uses the current scope, including built-ins. Restricting these dicts is crucial when evaluating dynamic content.
# Restrict built-ins and expose only what you needsafe_globals = {"__builtins__": {}}safe_locals = {"a": 2, "b": 5}print(eval("a * b", safe_globals, safe_locals)) # 10
Provide math safely
import math safe_globals = {"builtins": {}, "math": math} print(eval("math.sqrt(16)", safe_globals)) # 4.0
Security risks and safe alternatives
- Code execution risk:
eval()
can execute arbitrary code if the string is attacker-controlled. - Built-ins exposure: Access to
__import__
or dangerous functions via built-ins can lead to sandbox escapes. - Prefer parsing: Use
ast.literal_eval()
for safely evaluating Python literals like strings, numbers, tuples, lists, dicts, booleans, andNone
.
import ast
Safe for literals only (no function calls or attribute access)
print(ast.literal_eval("[1, 2, 3]")) # [1, 2, 3] print(ast.literal_eval("{'x': 1, 'y': 2}")) # {'x': 1, 'y': 2}
Never do this with untrusted input
eval(user_supplied_string)
compile() and expression vs statements
eval()
only handles expressions. To run statements (like loops or function definitions), use exec()
. You can pre-compile code with compile()
to validate mode and improve performance for repeated evaluations.
# Pre-compile an expressionexpr = compile("a + b", filename="", mode="eval")print(eval(expr, {"__builtins__": {}}, {"a": 3, "b": 4})) # 7
Compile statements (use exec, not eval)
stmts = compile("result = sum(range(5))", filename="", mode="exec") scope = {"builtins": {}} exec(stmts, scope) print(scope["result"]) # 10
Common patterns
- Whitelist-driven evaluation: Expose only approved functions/modules in
globals
, block built-ins. - Pre-validate input: Check strings against a regex or AST to ensure only expected constructs are present.
- Configuration formulas: Handle simple math expressions from trusted configs using a limited namespace.
# Whitelist math operations onlyimport operator as opallowed = {"add": op.add, "mul": op.mul}print(eval("add(2, mul(3, 4))", {"__builtins__": {}, **allowed})) # 14
Pitfalls and how to avoid them
- Untrusted input: Never pass user input directly to
eval()
. - Hidden built-ins: Omitting
__builtins__
won’t remove access unless you explicitly set it to an empty dict. - State leakage: Using the current scope can expose sensitive objects; prefer explicit
globals
/locals
. - Performance: Repeatedly evaluating strings incurs parse overhead; pre-compile when needed.
Practical examples
# 1) Evaluate a trusted formula with variablesformula = "base * (1 + rate)"globals_ = {"__builtins__": {}}locals_ = {"base": 100, "rate": 0.2}print(eval(formula, globals_, locals_)) # 120.0
2) Safe literal parsing from user settings
import ast settings = "{'retries': 3, 'timeout': 2.5}" cfg = ast.literal_eval(settings) print(cfg["timeout"]) # 2.5
3) Pre-compile for repeated use
code_obj = compile("x2 + y2", "", "eval") for x, y in [(1,2), (3,4), (5,6)]: print(eval(code_obj, {"builtins": {}}, {"x": x, "y": y}))
FAQ
- Can eval run statements?
- No.
eval()
is for expressions. Useexec()
for statements. - How do I make eval safer?
- Provide minimal
globals
/locals
, set__builtins__
to an empty dict, and whitelist only required functions. Preferast.literal_eval()
when possible. - Is eval fast?
- It incurs parsing overhead. For repeated use,
compile()
the expression andeval()
the code object.
Related keywords
Python eval, execute string code, globals locals, security, sandbox, ast.literal_eval, compile, exec, expression evaluation
comment list 0
There are no registered comments.