python : var's namespace code eval compiled ast code
Question: Using python3.4 and test the ast parse . Here is the test code .

    
    
    import ast
    import unittest
    
    
    class TestAST(unittest.TestCase):
    
        def test_ast(self):
            #compileobj = compile(ast.parse("x=42"), '<input>', mode="exec")
            #compile(ast.parse("x=42"), '<input>', mode="exec")
            eval(compile(ast.parse("x=42"), '<input>', mode="exec"))
            self.assertTrue(x == 42)
            pass
    
    
    if __name__ == '__main__':
        unittest.main()
    

python test.py I got error like this :

    
    
    Traceback (most recent call last):
      File "qocean\test\test_ast.py", line 13, in test_ast
        self.assertTrue(x == 42)
    NameError: name 'x' is not defined
    

While eval it in ipython : the x can be see like this :

    
    
    In [3]:  eval(compile(ast.parse("x=42"), '<input>', mode="exec"))
    
    In [4]: x
    Out[4]: 42
    

So the quetion is , while I can't use the var "x" , since the eval code is
same in source code and ipython eval environemt . What's the difference ?

`#############################################`

**Update** : seem it is something relate to unittest module ,change test code
in main() , it will success .

    
    
    if __name__ == '__main__':
        eval(compile(ast.parse("x=42"), '<input>', mode="exec"))
        print (x)
    

after run . it show 42 .

more detailed , call this in func also failed

    
    
    def test_eval():
        eval(compile(ast.parse("y=42"), '<input>', mode="exec"))
        print ("y is ", y)
    
    if __name__ == '__main__':
        #unittest.main()
        test_eval()
    


Answer: In Python 3, you can't create new local names dynamically. Those are baked in
at the time the function is compiled to bytecode. Instead, you need to pass a
dictionary to `exec` to be used as locals within that statement.

    
    
    def test_ast(self):
        localvars = {}
        eval(compile(ast.parse("x=42"), '<input>', mode="exec"), localvars)
        self.assertTrue(localvars["x"] == 42)
    

