Import Lib not working with exec function?

I have written the below code string and trying to execute it through the exec method. This code is running fine when I run it with global mode only.

codeRule = """import math
def fun (n):
    data = n
    data = data * math.pi
    print(data)
    return data
dd = fun(n)"""
    
codeObejct = compile(codeRule, 'sumstring', 'exec')
exec(codeObejct, dict(n = 10))

But my use case needs dd value outside of exec so I have used the below parameter to get dd value inside another dataframe.

loc = {}
exec(codeObejct, dict(n = 10), loc)
dd = loc["dd"]

But as soon as I use local it starts giving me an error regarding Lib Import such as

File "<stdin>", line 1, in <module>
  File "sumstring", line 7, in <module>
  File "sumstring", line 4, in fun
NameError: name 'math' is not defined

Can someone please help to solve this problem?

I have checked the below question’s answer but I don’t know how to fit it in my use case.

Why doesn’t an import in an exec in a function work?

Answer

Your answer looks good. Here’s another more-convoluted approach if you need a fallback for your use case:

codeRule = """
import math

def fun(n):
    data = n
    data = data * math.pi
    return data

loc['dd'] = fun(n)
"""

codeObject = compile(codeRule, 'sumstring', 'exec')
loc = {}
exec(codeObject, dict(n=10, loc=loc))
print(f"{loc['dd']=}")  # -> loc['dd']=31.41592653589793