Nico Schlömer
Nico Schlömer

Reputation: 58721

Python exec not picking up scope when called via a function

I have a function test() that should check if a string is a valid Python file. (The string is typically extracted from a readme or so.) Running exec() on the string works well, unless in this situation:

string = """
import math

def f(x):
    return math.sqrt(x)

f(2.0)
"""

# no problem:
# exec(string)


def test():
    exec(string)

test()  # NameError: name 'math' is not defined
Traceback (most recent call last):
  File "d.py", line 17, in <module>
    test()
  File "d.py", line 15, in test
    exec(string)
  File "<string>", line 7, in <module>
  File "<string>", line 5, in f
NameError: name 'math' is not defined

Why does exec() not pick up on the import math if called through a function, but works when running it in the main scope? How to work around it within test()?

Upvotes: 0

Views: 56

Answers (1)

Peaceful James
Peaceful James

Reputation: 2235

It's a bit hard to explain properly but it will work if you do this:

def test():
    exec(string, {"__MODULE__": "__main__"})

Basically, the import math does not exist in the f function unless it's declared in the main scope.

Upvotes: 1

Related Questions