Using Literal Eval for String-to-Object Conversion in Python

literal_eval is an interesting function from Python's built-in library ast. This function evaluates a string representation of any Python expression and executes it.

Prerequisites

  • Basic knowledge of Python

  • Python version: 3.10

Examples

For example, let's convert the string "True" to the boolean value True:

import ast
value = ast.literal_eval('True')

print(value) # output: True
print(type(value)) # output: <type 'bool'>

This command can also handle more complex instructions, like list:

import ast

value = ast.literal_eval("[1, 2, 3]")

print(value) # output: [1, 2, 3]
print(type(value)) # output: <type 'list'>

and dict:

import ast

value = ast.literal_eval("{'a': 1, 'b': 1, 'c': 42}")

print(value) # output: {'a': 1, 'b': 1, 'c': 42}
print(type(value)) # output: <type 'dict'>

Differences between eval and literal_eval

The literal_eval function is similar to the well-known eval command, but it only accepts a limited set of Python structures: strings, numbers, dictionaries, lists, tuples, boolean values (True or False), or None.

The eval command is more powerful, but it can be dangerous if you don't control the strings it processes. For example, running the command eval('rm -rf /') on a Linux system (please, DO NOT run this command) would delete all files from the root of the operating system. However, if you pass the same string to the literal_eval function, it will perform a security check before executing it and will raise a ValueError exception.

>>> ast.literal_eval("__import__('os').system('rm -rf /')")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.5/ast.py", line 84, in literal_eval
    return _convert(node_or_string)
  File "/usr/lib/python3.5/ast.py", line 83, in _convert
    raise ValueError('malformed node or string: ' + repr(node))
ValueError: malformed node or string: <_ast.Call object at 0x7f120ed568d0>

Conclusion

Despite the limitations on the types of structures accepted by literal_eval (which is not really an issue), it is recommended to use literal_eval instead of eval. The function's validation before executing an instruction can prevent many problems (as shown in the example above) and gives us better control over the code, as we know the types of structures it accepts as parameters.

References

0
Subscribe to my newsletter

Read articles from Michell Stuttgart directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Michell Stuttgart
Michell Stuttgart

I'm a backend Python developer, open source enthusiast, husband, Christian, and happy Linux user working from Brazil. brazil