Using python's eval vs. ast.literal_eval
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
eval and ast.literal_eval can both turn text into Python values, but they do not solve the same problem. eval executes a Python expression, while ast.literal_eval parses only literal data structures, which makes it far safer for input that might not be fully trusted.
What eval Really Does
eval does not just parse text. It executes Python expressions inside the interpreter.
This prints 14, which makes eval look convenient. The danger is that the input string can contain much more than arithmetic.
That code performs an import and a function call. If the string comes from a user, a file, or a network response, eval is effectively letting outside input run code in your process.
What ast.literal_eval Allows
ast.literal_eval is intentionally narrow. It accepts only Python literal structures such as:
- strings
- numbers
- tuples
- lists
- dictionaries
- booleans
- '
None'
This is useful when the input is supposed to represent data instead of executable logic. If the text contains a function call or other executable syntax, literal_eval rejects it.
That failure is exactly why literal_eval is safer for parsing data-like input.
Security Is the Real Difference
The core distinction is trust. If the input can be influenced by anyone outside your fully controlled code path, eval should be treated as dangerous by default.
Developers sometimes try to reduce the risk by passing restricted globals and locals to eval. That can narrow the environment, but it does not change the fundamental problem: you are still executing code. Sandboxing Python securely is much harder than it first appears.
ast.literal_eval is not a full sandbox either, but it is a much better fit when the goal is to parse literal values rather than run code.
JSON Is Often the Better Format
If the input comes from an API, config file, or message queue, JSON is usually a better format than Python literal syntax.
JSON is standardized, language-neutral, and easier to share across systems. ast.literal_eval is helpful when you specifically have Python-style literal text, but it should not be your first choice for general data exchange.
If You Need Expressions, Build a Narrow Evaluator
Sometimes the reason people reach for eval is that they want very small expression support, such as basic arithmetic in a rules field. In that case, a dedicated parser is usually safer and easier to reason about.
This approach explicitly defines what syntax is allowed. That is much safer than exposing general Python execution.
When eval Can Still Be Acceptable
There are narrow cases where eval is acceptable, such as internal tooling where the input is fully authored by trusted developers and dynamic expression support is intentional. Even then, it should be treated as a conscious design choice rather than a convenience parser.
If you use eval, document why the input is trusted and why a safer parser was not sufficient.
Common Pitfalls
The most common mistake is using eval as a shortcut for parsing user input because it feels convenient. That shortcut can quickly become a serious security bug.
Another mistake is assuming restricted globals automatically make eval safe. They may reduce risk in some cases, but they do not remove the fact that arbitrary code execution is the underlying behavior.
Developers also sometimes expect ast.literal_eval to handle expressions like 2 + 2. It will not, because it parses literals, not arbitrary expressions.
Finally, if the data is already JSON, use json.loads instead of forcing a Python-literal workflow.
Summary
- '
evalexecutes Python expressions and should be avoided for untrusted input.' - '
ast.literal_evalparses only literal Python data structures.' - Use JSON for most external data interchange.
- Build a narrow parser when you need limited expression support.
- Treat
evalas a security-sensitive tool, not a generic parser.

