compile()
Precompile source once; execute many times. Also the entry point for AST-based code transformation.
Common call
code = compile(src, "<str>", "exec")
Returns
a code object
Replaces
passing raw source to eval/exec every time
Watch out
the same security warnings as eval/exec — the code object still runs arbitrary Python
compile(sourcesource — The source code. String, bytes, or an ast.AST object (for AST-based tools).type: str | bytes | ast · required, filenamefilename — The filename used in error messages and tracebacks. Use "<str>" or "<stdin>" when the source is not from a file.type: str · required, modemode — "exec" for statements (any code), "eval" for a single expression, "single" for interactive single-statement mode.type: str · required, flagsflags — Compilation flags. Rarely set directly; the ast module uses this for feature flags like PyCF_ONLY_AST.type: int · default: 0=0, dont_inheritdont_inherit — Whether to inherit __future__ flags from the caller.type: bool · default: False=False, optimizeoptimize — Optimization level. -1 = current interpreter setting; 0 = none; 1 = -O; 2 = -OO (drop docstrings).type: int · default: -1=-1)
→ code
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| source | str | bytes | ast | yes | The source code. String, bytes, or an ast.AST object (for AST-based tools). |
| filename | str | yes | The filename used in error messages and tracebacks. Use "<str>" or "<stdin>" when the source is not from a file. |
| mode | str | yes | "exec" for statements (any code), "eval" for a single expression, "single" for interactive single-statement mode. |
| flags | int | no (0) | Compilation flags. Rarely set directly; the ast module uses this for feature flags like PyCF_ONLY_AST. |
| dont_inherit | bool | no (False) | Whether to inherit __future__ flags from the caller. |
| optimize | int | no (-1) | Optimization level. -1 = current interpreter setting; 0 = none; 1 = -O; 2 = -OO (drop docstrings). |
Return value
code — A compiled code object usable by eval, exec, or exec via direct call. Precompiling once and running many times is faster than passing the source string to eval/exec each iteration.
Common patterns
Precompile a hot code path
Same source run many times? Compile once.
code = compile(source, "<hot>", "exec") for row in rows: exec(code, {"row": row})
AST inspection
compile the source to an AST node first; walk it before executing.
import ast tree = compile(src, "<file>", "exec", flags=ast.PyCF_ONLY_AST) ast.walk(tree)
Explicit mode for eval
compile with mode="eval" for expressions; use eval() on the result.
code = compile("1 + 2", "<expr>", "eval") eval(code) # 3
For untrusted input — do NOT reach for compile
Precompiling untrusted source is still arbitrary code execution. compile is a performance tool for TRUSTED source, not a sandbox.
# BAD: compile(user_input, ...) — still unsafe # GOOD: use ast.literal_eval for data
Examples
1. For eval
c = compile("1 + 2", "<e>", "eval")
eval(c)
Returns
32. For exec
c = compile("x = 1", "<e>", "exec")
exec(c)
Returns
None (x is now 1)3. Type is code
type(compile("1", "<e>", "eval"))
Returns
<class 'code'>4. Wrong mode fails
compile("x = 1", "<e>", "eval")
Returns
SyntaxError: invalid syntax5. AST from source
compile(src, "<e>", "exec", ast.PyCF_ONLY_AST)
Returns
an ast.Module6. Syntax error
compile("x =", "<e>", "exec")
Returns
SyntaxErrorPitfalls
1. Mode "eval" requires an EXPRESSION, mode "exec" allows statements
A common typo. eval-mode rejects `x = 1` with SyntaxError; exec-mode accepts anything. Pick the mode that matches the source.
Wrong mode
compile("x = 1", "<e>", "eval")
SyntaxError: invalid syntax
Exec mode
compile("x = 1", "<e>", "exec")
code object
2. compile is NOT a sandbox
Precompiling untrusted source is still arbitrary code execution once it runs. compile is a performance and tooling primitive, not a security boundary.
False safety
code = compile(untrusted, ...) exec(code)
still executes user code
Use ast.literal_eval
import ast ast.literal_eval(untrusted)
literals only
3. The filename argument is for tracebacks, not the file system
compile does NOT read from a file — the filename is only used to label the code object for error messages. Pass a descriptive placeholder when the source is not from disk.
Assumed I/O
compile("data.txt", "data.txt", "exec")
compiles the literal string, not the file
Read first
src = open("data.txt").read() compile(src, "data.txt", "exec")
as intended
4. Optimize=2 drops docstrings — check before using
Optimize level 2 removes docstrings from the compiled code. Tools that read __doc__ (Sphinx, help(), doctest) will fail.
Docstrings gone
compile(src, "<e>", "exec", optimize=2)
__doc__ becomes None
Default optimize
compile(src, "<e>", "exec")
docstrings preserved
When to use
Use it
- Precompiling a template that runs many times
- AST-based code inspection or transformation
- Frameworks that generate and cache code (dataclasses, ORMs)
- Interactive REPLs that want single-statement mode
Reach for something else
- Untrusted source → not a sandbox
- A single one-shot exec → the compile overhead is not worth it
- Reading a file → do the reading yourself, then compile
- Data parsing → json / ast.literal_eval
Notes
Complexity
O(size of source) — a real parser runs
Return
A code object
CPython impl
Python/bltinmodule.c :: builtin_compile
Memory
Allocates a code object; smaller than source
Thread-safe
Yes for the compile step; execution depends on the code
FAQ
You should NOT — the compile overhead is wasted. Just pass the source to eval/exec directly. Precompile only when the same source runs multiple times.
History
1.0
compile() has been a builtin since Python 1.0.
2.6
Accepts ast.AST objects as source.
3.2
Added optimize parameter.