5 Easy Ways to Use ast.literal_eval() and its Functions

We often need a way to evaluate certain Python expressions inside our python code without getting into much trouble with malicious expressions. We can use ast.literal_eval() in our python code to achieve those things.

What is ast.literal_eval()?

“ast” class’ full form is Abstract Syntax Tree. It contains ast.literal_eval() function. It is used to evaluate trees of the Python abstract syntax grammar. Abstract syntax changes with each python release. Custom parsers are one use case of ast.literal_eval() function.

ast.literal_eval() acceptable parameters

We use the ast.literal_eval() to securely evaluate a Python string containing a literal or container display.
Only the following Python literal structures are permissible in the string passed to the ast.lietral_eval() such as:-

  1. Strings.
  2. Tuples.
  3. Dictionaries.
  4. Sets
  5. Lists
  6. Booleans
  7. Bytes
  8. Numbers
  9. None

We can only pass a string as an argument to ast.literal_eval() containing expression.

Its syntax is as follows:-

ast.literal_eval(a Python expression following above steps)

Why use ast.literal_eval()

Without us having to put effort into interpreting the contents, the ast.literal eval function securely evaluates strings containing Python values from malicious sources.
However, this function cannot evaluate complicated expressions including indexing or operators.

It throws an error if the input is not one of the known data types, as we saw above.

Some examples

There are various examples of how to use ast.literal_eval().

Let us see some examples:

In this example, we will be converting the string representation of a list into a list using ast.literal_eval():-

from ast import literal_eval
str = "['a','b','c','d']"
list = literal_eval(str)
print(list)
print(type(list))

The above code will have output as:-

It shows the output as a list of strings [a,b,c,d] and type as a list.
The output of the above code

We often compare eval() and ast.literal_eval(). They are not completely identical, even though they appear to do the same things as each other.

The ast.literal_eval() takes a bit more precaution and safeguards against any mishappening which can happen upon evaluating a python expression.

Let us see an example to understand better what I am talking about:-

The Ast.literal eval() will produce an error if you pass it

ast.literal_eval(__import ('os').system('rm -rf /a-path-you-really-care-about')

yet eval() will cheerfully erase your files.

Use ast.literal eval because it appears you only allow the user to enter a normal dictionary ().
The eval evaluates any expression and will begin deleting the files as soon as we implement the above expression. The ast.literal_eval() completes the above request without any headache.

The reason behind the restricted use of ast.literal_eval()

ast.literal_eval() function can act as a viable substitute for eval() since it is safe as compared to eval().
Additionally, parsing more complex expressions like multiplication, list/dictionary indexing, and function calls are ineffective due to the safety mechanisms built into the language.
Safety comes at a cost.

Python’s eval() vs ast.literal_eval()

Here we will be comparing python’s eval() and ast.literal_eval()

eval()literal_eval()
It doesn’t have any restrictions.It only accepts a portion of Python’s syntax as legitimate
It evaluates the code as soon as the function is called; we will have to evaluate its safety by ourselves.If the input is not a valid Python datatype, an exception is thrown, and the function is not performed.
It is really powerful, but it can be quite hazardous if we allow strings to be evaluated from untrusted input.Safely evaluate an expression node or a string containing a Python literal or container display.
Syntax:-eval(expression)Syntax:-ast.literal_eval(node_or_string)
Comparison table between eval() and ast.literal_eval()

What is its alternative?

The eval() is one of its alternatives, but it is not recommended as it is very powerful and can be dangerous.

The ast.parse() is another of its alternative, which can take a string as its input, parses, and then evaluates.

ast.parse(string, mode = 'eval')

What does malformed string mean?

The error “malformed string” occurs when the string passed for evaluation is incomprehensible.

E.g., the below snippet will produce an error, namely “malformed string”, as we have forgotten to represent a,b,c, and as separate strings.

ast.literal_eval("[a,b,c,d]")

The following code corrects the above problem:-

ast.literal_eval("["a","b","c","d"]")

Using ast.literal_eval() with pandas

Using AST’s literal_eval() function, we can handle more complex kinds of data in which a specific column may include an array of values rather than standard data types such as Strings, Integers, Timestamps, and so on.

ast.literal_eval() vs json.loads()

The json.loads() function parses a valid JSON string. It converts it to a Python dictionary. ast.literal_eval evaluates legitimate python expressions. ast.literal_eval() will work in the places where json.loads() won’t work.

ast.literal_eval() unexpected EOF while parsing

ast uses compile to convert the source string (which must be an expression) into an AST. If the source string is not a valid expression (for example, an empty string), compile will throw a SyntaxError “unexpected EOF while parsing”.

The below code throws a syntax error

ast.literal_eval(' ')

FAQs

How is an AST built?

Compilers frequently employ binary trees to create an interim visualization of the code that has not been completely compiled, known as an abstract syntax tree.

Can ASTs be called a data structure?

Yes, they can be called data structures; they are widely used in compilers.

Is an AST a binary tree?

Yes, a binary tree is used to build an AST.

Is AST parse safe?

Yes, it is safe and can be used over untrusted code. ast.literal_eval() firstly parses and then evaluates whatever is needed.

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments