Python eval()

Python provides a functionality wherein any expression passed as an argument can be evaluated explicitly. This unique Python concept/utility allows a Python program to run Python code within itself. For this purpose, the Python eval() built-in function is been specified. This function can be used for the dynamic evaluation of Python expressions from any input provided as a string or compiled code object.

Definition

• Python eval() function is used to parse an expression as an argument and then execute it within the Python program.
• The Python eval() is a built-in function that allows us to evaluate the Python expression as a ‘string’ and return the value as an integer.

Python eval()

Programmers can use the Python eval() function to dynamically evaluate expressions passed as a string argument to the built-in function. When a string is passed to Python eval(), it is parsed, compiled to bytecode, and then evaluated as a Python expression.

• Syntax

The syntax for eval() is:

                    
eval(expression, globals = None, locals = None)


• Python eval() Parameters

The eval() function accepts 3 values as its parameters. This Python built-in function accepts its first input named expression, which contains the expression to be evaluated. Python eval() then accepts two additional optional parameters.

expression = input parsed as a string and evaluated as a Python expression

globals (optional) = must be represented as a dictionary to specify available global variables and methods

locals (optional) = mapped object to specify available local variables and methods

Note – The current global and local namespaces are utilized if both globals and locals parameters are missing.

• Return value from eval()

The eval() method returns the result of the expression’s evaluation. In most cases, the return type will be an integer.

Example 1: How eval() works in Python

The eval() function is typically employed in situations or applications that require the evaluation of mathematical expressions.

Example 1

                    
# Python program to illustrate eval() function
print(eval('10 == 10'))

print(eval('2 ** 2'))

print(eval("'Pyt' + 'hon'"))

print(eval("'He' * 5"))

x = 10 + 59 - 23 * 5
print('Value of x is:', eval('x'))

print('Sum of list is:', eval('sum([2, 4, 6, 8])'))



Output

                    
True
4
Python
HeHeHeHeHe
Value of x is: -46
Sum of list is: 20



Example 2

                    
# Perimeter of Square
def calcPerimeter(l):
return 4*l

# Area of Square
def calcArea(l):
return l*l

print('Two functions declared are:')
print('1. calcPerimeter(l)')
print('2. calcArea(l)')
fnc = input('Type a function: ')

for l in range(1, 6):
if (fnc == 'calcPerimeter(l)'):
print('If length is:', l, ', Perimeter of Square = ', eval(fnc))
elif (fnc == 'calcArea(l)'):
print('If length is: ', l, ', Area of Square = ', eval(fnc))
else:
print('Wrong Function')
break



Output

                    
Two functions declared are:
calcPerimeter(l)
calcArea(l)
Type a function: calcPerimeter(l)
If length is: 1 , Perimeter of Square =  4
If length is: 2 , Perimeter of Square =  8
If length is: 3 , Perimeter of Square =  12
If length is: 4 , Perimeter of Square =  16
If length is: 5 , Perimeter of Square =  20



Warnings when using eval()

Let us assume we have imported an ‘os’ module while working on a Unix system such as MacOS, Linux, etc. Now, this ‘os’ module provides a flexible way to exploit operating system features such as reading and writing files. If you allow users to enter a value using eval(input()), the user can use the command: os.system(‘rm -rf *’) to modify, alter or even remove all files of the OS. Furthermore, you should never directly send an untrusted source to eval(). Because it is quite simple for a rogue user to cause havoc to the system.

One solution to avoid this problem is to use the dir() method. You may view all of the variables and methods that are available. It’s a good idea to double-check the variables and methods that the user has access to.

                    
from math import *
print(eval(‘dir()’))



Output

                    
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__',
'__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'comb', 'copysign',
'cos', 'cosh', 'degrees', 'dist', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod',
'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'isqrt', 'ldexp',
'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'perm', 'pi', 'pow', 'prod', 'radians', 'remainder',
'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc']



Restricting the use of Available Methods and Variables in eval()

Another solution is to limit eval() to only the functions and variables that we want to use and expose. This is when global and local parameters come into play. Limiting the use of eval() by passing globals and locals dictionaries makes the code more secure, especially when providing user input to the eval() method.

1. When both the globals and the locals parameters are ignored

As we have discussed in the above example, the expression is executed in the current scope.

                    
print(eval(‘dir()’))



1. Passing globals parameter & locals parameter omitted

In this case, if the locals dictionary parameter is not specified, then it automatically defaults to the globals dictionary. It means the global variables and methods will be used for both the globals and locals variables.

Note – In Python, you may check the current global and local dictionaries using the built-in functions globals() and locals().

                    
from math import *
def square_root(n):
return sqrt(n)

print(globals())



Output

                    
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>,
'acos': , 'acosh': , 'asin': , 'asinh': , 'atan': , 'atan2': , 'atanh': ,
'ceil': , 'copysign': , 'cos': , 'cosh': , 'degrees': , 'dist': , 'erf': ,
'erfc': , 'exp': , 'expm1': , 'fabs': , 'factorial': , 'floor': , 'fmod': ,
'frexp': , 'fsum': , 'gamma': , 'gcd': , 'hypot': , 'isclose': , 'isfinite': ,
'isinf': , 'isnan': , 'isqrt': , 'ldexp': , 'lgamma': , 'log': , 'log1p': ,
'log10': , 'log2': , 'modf': , 'pow': , 'radians': , 'remainder': , 'sin': ,
'sinh': , 'sqrt': , 'tan': , 'tanh': , 'trunc': , 'prod': , 'perm': , 'comb': ,
'pi': 3.141592653589793, 'e': 2.718281828459045, 'tau': 6.283185307179586, 'inf': inf, 'nan': nan, 'square_root': }


1. Passing empty dictionary as a globals parameter

Let’s explore what happens if we pass the globals value as an empty dictionary to the eval() function.

Example

                    
from math import *
print(eval('dir()', {}))
print(‘’)

# This will raise an exception
print(eval('sqrt(36)', {}))



Output

                    
['__builtins__']

Traceback (most recent call last):
File "", line 5, in
print(eval('sqrt(36)', {}))
File "", line 1, in
NameError: name 'sqrt' is not defined



Explanation

In the first print statement, we have passed an empty dictionary as globals parameter. This will only return __builtins__ that denotes only this module will be available for the ‘expression’.

Even though we have imported the math module, you may notice that the ‘expression’ parameter cannot access the sqrt function of the math module, because the globals argument value assigned is an empty dictionary.

1. Making certain methods and functions available

Considering the above example, if we want to make only a specific function available for functioning, we can specify it by using the following method:

Example

                    
from math import *
fnc = {'sqrt': sqrt}
print(eval('dir()', fnc))   # fnc passed as globals parameter
print(eval('sqrt(36)', fnc))

#OR
print(eval('dir()', {'sqrt': sqrt}))   # entire dictionary passed as globals parameter
print(eval('sqrt(36)', {'__builtins__':{'sqrt': sqrt}}))



Output

                    
['__builtins__', 'sqrt']
6.0
['__builtins__', 'sqrt']
6.0



Explanation

Here, you can see that the sqrt built-in function has been activated and the expression has been executed in the next print statement.

1. Passing both globals and local dictionary

Here, we have defined both the globals dictionary and locals mapping objects. The ‘expression’ parameter can only access floor() method and variable ‘a’ and ‘num’ in the program below. All the other functions and methods will be unavailable.

Example

                    
from math import *

globals = {'a': 10.6439, 'floor': floor}
locals = {'num': 10}

print('Value is:', eval('floor(a) + num', globals, locals))



Output

                    
Value is: 20



Q1. What does eval() do in Python?

The Python eval() is a built-in function that allows us to evaluate the Python expression as a ‘string’ and return the value as an integer. Programmers can use the Python eval() function to dynamically evaluate expressions passed as a string argument to the built-in function. When a string is passed to Python eval(), it is parsed, compiled to bytecode, and then evaluated as a Python expression. The Python eval() function is typically employed in situations or applications that require the evaluation of mathematical expressions.

The syntax for eval() is:

                    
eval(expression, globals = None, locals = None)



The eval() function accepts 3 values as its parameters. This Python built-in function accepts its first input named expression, which contains the expression to be evaluated. Python eval() then accepts two additional optional parameters.

expression = input parsed as a string and evaluated as a Python expression

globals (optional) = must be represented as a dictionary to specify available global variables and methods

locals (optional) = mapped object to specify available local variables and methods

Q2. Why is the eval() function bad in Python?

If you use eval() on a string that could be manipulated by a malicious entity, you could end up running malicious code on the user’s machine. More crucially, a third-party code can know the scope in which eval() was used, which might lead to various attacks that need mathematical equations to be evaluated.

One example to understand this can be if you allow users to enter a value using eval(input()), the user can use the command: os.system(‘rm -rf *’) to modify, alter or even remove all files of the OS.

Avoiding eval() code simplifies debugging by allowing you to simply inspect and step through the code. That doesn’t necessarily make eval() bad; it’s simply problematic in a typical development approach.

Q3. Is the eval() function safe in Python?

Because it allows the users to dynamically execute arbitrary Python code, eval() is considered unsafe. If you want to use eval() to evaluate information from a user or another external source, you won’t know what code will be performed. If your application falls into the wrong hands, this poses a major security risk. There is no totally effective solution to eliminating the security hazards associated with eval when the input is untrusted (). You can, however, reduce your risk by limiting the execution context of eval ().

Share with friends

Customize your course in 30 seconds

Which class are you in?
5th
6th
7th
8th
9th
10th
11th
12th
Get ready for all-new Live Classes!
Now learn Live with India's best teachers. Join courses with the best schedule and enjoy fun and interactive classes.
Ashhar Firdausi
IIT Roorkee
Biology
Dr. Nazma Shaik
VTU
Chemistry
Gaurav Tiwari
APJAKTU
Physics
Get Started