Python eval(): Execute code from strings — syntax, globals and locals, security risks, safe alternatives, compile(), common patterns, and examples > dev

Skip to content

Entire search within the site

👈Go back dev

Python Python eval(): Execute code from strings — syntax, globals and locals,…

page info

name Goposu datetime⏰ 25-10-11 17:41 hit👁️ 10 comment💬 0

text

Python eval(): Execute code from strings — syntax, globals and locals, security risks, safe alternatives, compile(), common patterns, and examples

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, or import).
  • 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, and None.
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. Use exec() for statements.
How do I make eval safer?
Provide minimal globals/locals, set __builtins__ to an empty dict, and whitelist only required functions. Prefer ast.literal_eval() when possible.
Is eval fast?
It incurs parsing overhead. For repeated use, compile() the expression and eval() the code object.

Related keywords

Python eval, execute string code, globals locals, security, sandbox, ast.literal_eval, compile, exec, expression evaluation

👍good0 👎nogood 0

comment list 0

There are no registered comments.

이미지 목록

전체 19건 1 페이지
게시물 검색
Copyright © https://goposu.com All rights reserved.
View PC version