eval() in Python 2026: Dynamic Expression Evaluation + Security Risks & Safe Alternatives
The built-in eval() function evaluates a string as a Python expression and returns the result. In 2026 it remains one of the most powerful — and most dangerous — built-ins, used for dynamic calculation, configuration parsing, interactive shells, and some metaprogramming scenarios. However, its ability to execute arbitrary code makes it a top security risk when handling untrusted input.
With Python 3.12–3.14+ offering better AST parsing, improved restricted execution tools, and growing security best practices (restrictedpython, ast.literal_eval, sandboxing), eval() is used far more cautiously. This March 23, 2026 update explains how eval() works today, real-world (trusted) use cases, severe security warnings, performance notes, and modern safe alternatives.
TL;DR — Key Takeaways 2026
eval(expression, globals=None, locals=None)→ executes string as Python expression- 2026 security rule: NEVER use eval() on untrusted input — remote code execution risk
- Safe alternative:
ast.literal_eval()for simple literals (int, str, list, dict…) - Main safe use cases: trusted config expressions, interactive REPLs, calculator apps
- Performance: Fast for small expressions — cache compiled code objects if reused
1. Basic Usage — Evaluating Expressions
x = 10
print(eval("x * 2 + 5")) # 25
# With custom globals/locals (safer)
safe_globals = {"__builtins__": {}, "x": x}
print(eval("x * 3", safe_globals)) # 30
2. Real-World Patterns in 2026 (Trusted Input Only!)
Trusted Config Expression Evaluation
def load_expression(expr: str) -> float:
# WARNING: Only use on trusted config!
safe_globals = {"__builtins__": {}, "pi": 3.14159, "sin": math.sin}
return eval(expr, safe_globals)
# Trusted example (from your own config)
result = load_expression("sin(pi/2) + 1")
print(result) # 2.0
Simple Calculator / Interactive Shell
def simple_calculator():
while True:
expr = input("Enter expression (or q to quit): ")
if expr.lower() == "q":
break
try:
print(eval(expr))
except Exception as e:
print(f"Error: {e}")
3. Security Risks & Modern Alternatives in 2026
| Approach | Security Level | Use Case | Recommendation 2026 |
|---|---|---|---|
| eval(expr) | Very low (arbitrary code exec) | Never with user input | Avoid completely in untrusted contexts |
| ast.literal_eval(expr) | High (safe literals only) | Config, simple data structures | Preferred for safe parsing |
| restrictedpython / safe_eval | Medium–High | Restricted dynamic expressions | Use for semi-trusted plugins |
| subprocess / separate process | Very high | Untrusted code | Safest for unknown sources |
4. Best Practices & Performance in 2026
- Never eval untrusted input — use ast.literal_eval() for safe literals
- Restrict globals — always pass {"__builtins__": {}} or safe namespace
- Type hints 2026:
from typing import Any def safe_eval(expr: str, safe_globals: dict[str, Any]) -> Any: return eval(expr, {"__builtins__": {}} | safe_globals, {}) - Performance: compile once with compile(), then eval() multiple times
- Free-threading (3.14+): Safe when globals/locals are not modified concurrently
Conclusion — eval() in 2026: Powerful but Highly Restricted
eval() allows dynamic expression evaluation — useful for trusted calculators, configs, and metaprogramming — but it is one of Python’s biggest security risks when misused. In 2026, restrict it to trusted sources, prefer ast.literal_eval() for safe cases, and use restricted environments or subprocess for anything untrusted. When used correctly, it’s a clean way to run dynamic math expressions at runtime.
Next steps:
- Audit your codebase for eval() — replace untrusted uses immediately
- Related articles: compile() in Python 2026 • Efficient Python Code 2026