Python3: Will objects declared in a file run by exec() interfere with other files run by exec()?

Viewed 20

I TA an introduction computer science course, the students were given a lottery problem where they input 2 guesses via args to guess at 2 randomly generated numbers. I wrote this script to help with getting output and testing specific cases, the professor is worried that:

"variables and objects from individual runs of student code will remain in the environment for the duration of your script. This could cause side-effects which cause or mask problems in subsequent runs for other students."

Could this be an actual issue? See code below:

import os
import random
import sys
import re

guessList = [(2,5), (7, 2), (3, 10), (8, 2), (9, 5), (3, 1), (8, 9)]

for root, dirs, files in os.walk(".", topdown=False):
    # iterate through each folder in directory
    for name in dirs:    
        student = os.path.join(root, name)
        student_name = re.search('([a-zA-Z]{2,}) ([a-zA-Z]{2,})', student).group()
        print("\nStudent:", student_name)
        print("-----------------------------------------------")        
         
        # reset seed: nums generated: 10 1 7 8 10 1 4 8 8 5 3 1 9 8
        random.seed(10) 

        # loop through test cases
        for guess in guessList:
            # input
            sys.argv = ['', guess[0], guess[1] ] 
            # run student's script
            try:
                exec(open(f"{student}/Lottery.py").read() )
            except Exception as e: 
                print("ERROR HAS OCCURED:")
                print(e)
                break 
        print("-----------------------------------------------\n")
1 Answers

The concern of namespace pollution that the professor has is legitimate, and in this very case I would use subprocess.check_output instead to run each student's script with a completely separate Python command:

import subprocess

...

output = subprocess.check_output(['python', f"{student}/Lottery.py", guess[0], guess[1]])

If you do what @KarlKnechtel says in the comment and exec the student's script with empty dicts as globals and locals arguments to ensure a separate namespace:

exec(open(f"{student}/Lottery.py").read(), {}, {})

the script would not get some of the important and commonly used dunder variables normally supplied by the Python interpreter, such as __file__ and __name__, which you would then have to manage and supply to the globals dict you pass to exec, an unnecessary hassle to deal with.

Related