title: Python eval(compile(...), sandbox), globals go in sandbox unless in def, why?
body: <p>Consider the following:</p>
  
  <pre><code>def test(s):
      globals()['a'] = s
  
  sandbox = {'test': test}
  py_str = 'test("Setting A")\nglobals()["b"] = "Setting B"'
  eval(compile(py_str, '&lt;string&gt;', 'exec'), sandbox)
  
  'a' in sandbox # returns False, !What I dont want!
  'b' in sandbox # returns True, What I want
  'a' in globals() # returns True, !What I dont want!
  'b' in globals() # returns False, What I want
  </code></pre>
  
  <p>I'm not even sure how to ask, but I want the global scope for a function to be the environment I intend to run it in without having to compile the function during the eval. Is this possible?</p>
  
  <p>Thanks for any input</p>
  
  <p><strong>Solution</strong></p>
  
  <pre><code>def test(s):
      globals()['a'] = s
  
  sandbox = {}
  
  # create a new version of test() that uses the sandbox for its globals
  newtest = type(test)(test.func_code, sandbox, test.func_name, test.func_defaults,
                       test.func_closure)
  
  # add the sandboxed version of test() to the sandbox
  sandbox["test"] = newtest
  
  py_str = 'test("Setting A")\nglobals()["b"] = "Setting B"'
  eval(compile(py_str, '&lt;string&gt;', 'exec'), sandbox)
  
  'a' in sandbox # returns True
  'b' in sandbox # returns True
  'a' in globals() # returns False
  'b' in globals() # returns False
  </code></pre>