Python exec Function – Example and Risk

1. Objective – Python exec

Over the days, we have begun discussing a few Python built-in functions we see commonly in use. Today, we will see Python exec tutorial. Moreover, we will see the exact meaning of Python exec. Also, we will discuss Python exec() example with syntax. At last, we will look at risk with exec in Python.
So, let’s start the Python exec tutorial.

Python exec Function - Example and Risk

Python exec Function – Example and Risk

2. What is Python exec()?

To say it again, exec() is a built-in function/ method with Python.

>>> type(exec)

<class ‘builtin_function_or_method’>
Let’s check the help for this.

>>> help(exec)

Help on built-in function exec in module builtins:
exec(source, globals=None, locals=None, /)
Execute the given source in the context of globals and locals.
The source may be a string representing one or more Python statements
or a code object as returned by compile().
The globals must be a dictionary and locals can be any mapping,
defaulting to the current globals and locals.
If only globals is given, locals defaults to it.

a. Python exec Syntax

Let’s see what this means:
The source can be a string that denotes one or more Python statements
The source can be a code object that the compile() function returns
The globals is a dictionary- the current is the default
The locals can be any kind of mapping- the current is the default; dictionary is the common mapping type with Python
This function executes the source in the context of globals and locals
If we only mention globals, the locals are that by default

b. Using exec() in Python

We use exec() to dynamically execute Python code- this can be a string or some object code. When it is a string, Python parses it as a set of statements and executes it if there is no syntax error. When it is object code, Python executes it. But exec() doesn’t return a value; it returns None. Hence, we cannot use return and yield statements outside function definitions.

3. Python exec Example

Let’s begin with a simple example of Python exec. For now, let’s skip the globals and locals parameters.

>>> code='a=7\nprint("a*17=",a*17)'
>>> exec(code)

a*17= 119

a. Dynamic Execution With User Input

If we can get the user to provide input at the time of execution, we can dynamically execute Python code. How cool is that?

>>> code=input('What would you like to do today?')

What would you like to do today?[print(x**2) for x in range(7)]

>>> exec(code)

0
1
4
9
16
25
36

b. Python exec vs eval:

If we try doing this to create a list with Python exec:

>>> exec('[(x**2) for x in range(7)]')
>>>

Nothing happens! We must use Python eval instead:

>>> eval('[(x**2) for x in range(7)]')

 [0, 1, 4, 9, 16, 25, 36]
Let’s discuss Python Forensics

Python Interview Questions

4. Risks With Exec in Python

a. Problem in Python exec

When you give your users the liberty to execute any piece of code with the Python exec() function, you give them a way to bend the rules. What if you have access to the os module in your session and they borrow a command from that to run? Say you have imported os in your code.

>>> import os
>>> code=input('What would you like to do today?')

What would you like to do today?print(os.listdir())

>>> exec(code)

[‘DLLs’, ‘Doc’, ‘etc’, ‘hacked.dll’, ‘include’, ‘Lib’, ‘libs’, ‘LICENSE.txt’, ‘man’, ‘NEWS.txt’, ‘opencv_ffmpeg343.dll’, ‘out.log’, ‘python.exe’, ‘python3.dll’, ‘python37.dll’, ‘pythonw.exe’, ‘Scripts’, ‘share’, ‘tcl’, ‘Tools’, ‘vcruntime140.dll’]
Worse, they can corrupt or even delete all your files and directories. Consider we have a directory demo with three text files:
In the directory four, we have another text file:

>>> os.chdir('\\demo') #The path of your demo folder
>>> os.listdir()

[‘four’, ‘one.txt’, ‘three.txt’, ‘two.txt’]
Now, what if the user runs this command:

Join DataFlair on Telegram
>>> code=input('What would you like to do today?')

What would you like to do today?os.system(‘rm -rf *’)

>>> exec(code)

This will delete all your files in the current location! Since exec compiles and evaluates any expression you give it, it is often more risqué than eval and pickle.

b. Solution of Python exec Problem

You can check which variables and methods are available to the user. Use the dir() method for this.

>>> dir()

[‘__annotations__’, ‘__builtins__’, ‘__doc__’, ‘__loader__’, ‘__name__’, ‘__package__’, ‘__spec__’]

>>> a=7
>>> def hello(): print("Hello")
>>> dir()

[‘__annotations__’, ‘__builtins__’, ‘__doc__’, ‘__loader__’, ‘__name__’, ‘__package__’, ‘__spec__’, ‘a’, ‘hello’]

>>> from os import *
>>> dir()

[‘DirEntry’, ‘F_OK’, ‘O_APPEND’, ‘O_BINARY’, ‘O_CREAT’, ‘O_EXCL’, ‘O_NOINHERIT’, ‘O_RANDOM’, ‘O_RDONLY’, ‘O_RDWR’, ‘O_SEQUENTIAL’, ‘O_SHORT_LIVED’, ‘O_TEMPORARY’, ‘O_TEXT’, ‘O_TRUNC’, ‘O_WRONLY’, ‘P_DETACH’, ‘P_NOWAIT’, ‘P_NOWAITO’, ‘P_OVERLAY’, ‘P_WAIT’, ‘R_OK’, ‘SEEK_CUR’, ‘SEEK_END’, ‘SEEK_SET’, ‘TMP_MAX’, ‘W_OK’, ‘X_OK’, ‘__annotations__’, ‘__builtins__’, ‘__doc__’, ‘__loader__’, ‘__name__’, ‘__package__’, ‘__spec__’, ‘_exit’, ‘a’, ‘abort’, ‘access’, ‘altsep’, ‘chdir’, ‘chmod’, ‘close’, ‘closerange’, ‘cpu_count’, ‘curdir’, ‘defpath’, ‘device_encoding’, ‘devnull’, ‘dup’, ‘dup2’, ‘environ’, ‘error’, ‘execl’, ‘execle’, ‘execlp’, ‘execlpe’, ‘execv’, ‘execve’, ‘execvp’, ‘execvpe’, ‘extsep’, ‘fdopen’, ‘fsdecode’, ‘fsencode’, ‘fspath’, ‘fstat’, ‘fsync’, ‘ftruncate’, ‘get_exec_path’, ‘get_handle_inheritable’, ‘get_inheritable’, ‘get_terminal_size’, ‘getcwd’, ‘getcwdb’, ‘getenv’, ‘getlogin’, ‘getpid’, ‘getppid’, ‘hello’, ‘isatty’, ‘kill’, ‘linesep’, ‘link’, ‘listdir’, ‘lseek’, ‘lstat’, ‘makedirs’, ‘mkdir’, ‘name’, ‘open’, ‘os’, ‘pardir’, ‘path’, ‘pathsep’, ‘pipe’, ‘popen’, ‘putenv’, ‘read’, ‘readlink’, ‘remove’, ‘removedirs’, ‘rename’, ‘renames’, ‘replace’, ‘rmdir’, ‘scandir’, ‘sep’, ‘set_handle_inheritable’, ‘set_inheritable’, ‘spawnl’, ‘spawnle’, ‘spawnv’, ‘spawnve’, ‘startfile’, ‘stat’, ‘stat_result’, ‘statvfs_result’, ‘strerror’, ‘supports_bytes_environ’, ‘symlink’, ‘system’, ‘terminal_size’, ‘times’, ‘times_result’, ‘truncate’, ‘umask’, ‘uname_result’, ‘unlink’, ‘urandom’, ‘utime’, ‘waitpid’, ‘walk’, ‘write’]
Let’s talk about Python Closure 

c. Globals and Locals Parameters

Using the globals and locals parameters, we can restrict what variables and methods users can access. We can either provide both, or just the globals, in which case that value suffices for both- globals and locals. At module level, globals and locals are the same dictionary.
The globals parameter-
Let’s take an example of global and local parameter in Python exec.

>>> from math import *
>>> exec('print(dir())')

[‘__annotations__’, ‘__builtins__’, ‘__doc__’, ‘__loader__’, ‘__name__’, ‘__package__’, ‘__spec__’, ‘acos’, ‘acosh’, ‘asin’, ‘asinh’, ‘atan’, ‘atan2’, ‘atanh’, ‘ceil’, ‘copysign’, ‘cos’, ‘cosh’, ‘degrees’, ‘e’, ‘erf’, ‘erfc’, ‘exp’, ‘expm1’, ‘fabs’, ‘factorial’, ‘floor’, ‘fmod’, ‘frexp’, ‘fsum’, ‘gamma’, ‘gcd’, ‘hypot’, ‘inf’, ‘isclose’, ‘isfinite’, ‘isinf’, ‘isnan’, ‘ldexp’, ‘lgamma’, ‘log’, ‘log10’, ‘log1p’, ‘log2’, ‘modf’, ‘nan’, ‘pi’, ‘pow’, ‘radians’, ‘remainder’, ‘sin’, ‘sinh’, ‘sqrt’, ‘tan’, ‘tanh’, ‘tau’, ‘trunc’]
And now with an empty dictionary for globals:

>>> exec('print(dir())',{})

[‘__builtins__’]
This only lets the __builtins__ be available to the object. Want to know more about __builtins__? Check the help for it:

>>> help(__builtins__)

Help on built-in module builtins:
NAME
 builtins – Built-in functions, exceptions, and other objects.
You must read Python Function Arguments
We can confirm the unavailability of the math functions with another example:

>>> exec('print(tan(90))')

 -1.995200412208242

>>> exec('print(tan(90))',{})

Traceback (most recent call last):
 File “<pyshell#4>”, line 1, in
 exec(‘print(tan(90))’,{})
 File “”, line 1, in
NameError: name ‘tan’ is not defined
If, here, we want only the tan function to be available, we can do that too:

>>> exec('print(tan(90))',{'tan':tan})

-1.995200412208242
Didn’t we say it was a dictionary? Anyway, we can also call it anything else.

>>> exec('print(tanx(90))',{'tanx':tan})

 -1.995200412208242
The globals and locals parameters-
Let’s try giving it both.

>>> exec('print(dir())',{'built':__builtins__},{'sum':sum,'iter':iter})

[‘iter’, ‘sum’]
This lets the user execute the sum() and iter() methods along with the __builtins__. We can also keep the user from availing any builtins:
Let’s revise Decorators in Python

>>> exec('print(dir())',{'__builtins__':None},{'sum':sum,'print':print,'dir':dir})

[‘dir’, ‘print’, ‘sum’]
You can also use the built-in globals() and locals() functions for this.

>>> exec('print(dir())',globals(),locals())

[‘__annotations__’, ‘__builtins__’, ‘__doc__’, ‘__loader__’, ‘__name__’, ‘__package__’, ‘__spec__’, ‘acos’, ‘acosh’, ‘asin’, ‘asinh’, ‘atan’, ‘atan2’, ‘atanh’, ‘ceil’, ‘copysign’, ‘cos’, ‘cosh’, ‘degrees’, ‘e’, ‘erf’, ‘erfc’, ‘exp’, ‘expm1’, ‘fabs’, ‘factorial’, ‘floor’, ‘fmod’, ‘frexp’, ‘fsum’, ‘gamma’, ‘gcd’, ‘hypot’, ‘inf’, ‘isclose’, ‘isfinite’, ‘isinf’, ‘isnan’, ‘ldexp’, ‘lgamma’, ‘log’, ‘log10’, ‘log1p’, ‘log2’, ‘modf’, ‘nan’, ‘pi’, ‘pow’, ‘radians’, ‘remainder’, ‘sin’, ‘sinh’, ‘sqrt’, ‘tan’, ‘tanh’, ‘tau’, ‘trunc’]
So, this was all in Python exec Function. hope you like our explanation.

5. Conclusion – Exec in Python

Hence, n this Python exec tutorial, we will say that exec supports dynamic execution of Python code. Moreover, we discussed the meaning of exec in Python. Also, we saw Python exec example. At last, we discussed risk with exec in Python. Still, if you have any confusion, ask in the comment tab.
See also – 
Python Ternary Operator
For reference

Leave a Reply

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.