Shophaune
Shophaune

Reputation: 5

What am I missing with accessing custom globals in exec()?

With my project, I have small user-defined python programs stored in files that I need to have access to some variables in the main program - I am running these through exec() with a custom global list (to minimise the ability for malevolent code to function). However, whilst passing functions in this list seems to work, passing the main program's variables doesn't work.

Main program:

lessonCorrect = False
safeAccessForLessons = {'__builtins__':{}, 'print':print,
                        'lessonCorrect':lessonCorrect}

try:
    exec("""
print('Found!')
x = 3
y = 4
print(x,y,x+y,x*y)
global lessonCorrect
print(lessonCorrect)
lessonCorrect = True
print(lessonCorrect)""", safeAccessForLessons)
    print(lessonCorrect)
except:
    print("Blah")
    import sys
    print(sys.exc_info())

Output:

>>> checkLesson()
Found!
3 4 7 12
False #First print in file
True #Second print in file
False #Print in function

Expected Output:

>>> checkLesson()
Found!
3 4 7 12
<unimportant> #First print in file
True #Second print in file
True #Print in function

Upvotes: 0

Views: 36

Answers (1)

Arthur
Arthur

Reputation: 4251

The issue here is not with exec, but rather with how you are accessing the lessonCorrect variable.

See this for instance:

lessonCorrect = False
safeAccessForLessons = {'lessonCorrect': lessonCorrect}
safeAccessForLessons['lessonCorrect'] = True
print('dict', safeAccessForLesssons)
print('var', lessonCorrect)

This will output:

dict {'lessonCorrect': True}
var False

And so, to get back to your code, here the exec call is modifying the safeAccessForLessons dict, but is never touching the lessonCorrect variable. So instead of doing print(lessonCorrect) in checkLesson, you can do print(safeAccessForLesssons['lessonCorrect']) and you will get what you want

Upvotes: 1

Related Questions