compile() is a built-in Python function that compiles source code (string or AST) into a code object — enabling dynamic execution via exec() or eval(), or inspection via dis. It supports modes ('exec', 'eval', 'single'), flags, optimization levels, and custom namespaces. In 2026, compile() remains essential for metaprogramming, dynamic code generation, REPLs, template engines, scientific computing (expression evaluation), and secure eval alternatives — especially when combined with ast for safe parsing, restricted execution, or code transformation pipelines.
Here’s a complete, practical guide to using compile() in Python: syntax & modes, basic execution, AST integration, real-world patterns (earthquake expression evaluator, dynamic filters, template engine), and modern best practices with type hints, security, performance, error handling, and integration with Dask/Polars/pandas/xarray.
Basic compile() — compile string to code object, execute with exec or eval.
# Mode 'exec' — statements (multiple lines)
code_str = """
x = 10
print(f"The value of x is {x}")
"""
code_obj = compile(code_str, '', 'exec')
exec(code_obj) # Output: The value of x is 10
# Mode 'eval' — single expression
expr = "2 ** 8 + 5"
code_eval = compile(expr, '', 'eval')
result = eval(code_eval)
print(result) # 261
# Mode 'single' — single interactive statement
single_code = compile("print('Hello')", '', 'single')
exec(single_code) # Hello
Advanced compilation — flags, dont_inherit, optimize, custom namespaces.
# Compile with future flags (e.g., annotations)
from __future__ import annotations
code = compile("def f(x: int) -> str: return str(x)", '', 'exec', flags=0x10000)
# Custom globals/locals
my_globals = {'__builtins__': {}} # restricted builtins
my_locals = {}
exec(compile("x = 42\nprint(x)", '', 'exec'), my_globals, my_locals)
print(my_locals['x']) # 42
# Optimized compilation (-O level)
opt_code = compile("x = 1 + 2", '', 'exec', optimize=1)
print(opt_code.co_flags) # shows optimization flags
Real-world pattern: dynamic expression evaluation for earthquake filtering — safe & flexible queries.
import pandas as pd
df = pd.read_csv('earthquakes.csv')
def safe_filter(df: pd.DataFrame, expr: str) -> pd.DataFrame:
"""Compile & eval user expression safely."""
try:
code = compile(expr, '', 'eval', dont_inherit=True)
mask = df.eval(code, engine='python') # uses pandas eval
return df[mask]
except Exception as e:
raise ValueError(f"Invalid expression: {expr}") from e
# Usage examples
strong = safe_filter(df, 'mag >= 7.0')
print(strong.shape)
deep_strong = safe_filter(df, '(mag >= 6.5) and (depth <= 70)')
print(deep_strong.head())
# With variables
threshold = 6.0
filtered = safe_filter(df, f'mag >= {threshold}')
Best practices for compile() in Python & data workflows. Prefer ast.parse() + ast.literal_eval() — for safe constant expressions. Modern tip: use Polars pl.col('mag') >= 7.0 — safer & faster than dynamic compile/eval. Restrict namespaces — pass empty/bare globals to exec/eval. Use dont_inherit=True — avoid inheriting future flags. Set optimize=-1 — disable optimizations for debugging. Add type hints — def compile_safe(code: str, mode: str = 'exec') -> types.CodeType. Catch SyntaxError/TypeError — user-friendly errors. Avoid exec/eval on untrusted input — security risk. Use ast — for code inspection/transformation. Use dis — disassemble compiled code. Use inspect — get source from code objects. Use compile() in DSLs — dynamic queries, config-driven logic. Profile performance — compile once, exec many times. Use exec(compile(...), safe_globals, safe_locals) — restricted execution. Use RestrictedPython — safer alternative for untrusted code.
compile() compiles source to code objects — enabling dynamic exec/eval, AST manipulation, and custom execution environments. In 2026, use safely with restricted namespaces, prefer Polars/Dask for data queries, ast.literal_eval for constants, and avoid eval on untrusted input. Master compile(), and you’ll build dynamic, powerful, and secure code evaluation systems for any Python project.
Next time you need to execute or inspect dynamic code — use compile(). It’s Python’s cleanest way to say: “Turn this string into executable code — safely and efficiently.”