Getting namespaces right when parsing/executing Python ASTs

Gordon Fraser gfraser79 at gmail.com
Tue Oct 7 14:26:50 CEST 2008


Hi,

I'm trying to parse Python code to an AST, apply some changes to the AST
and then compile and run the AST, but I'm running into problems when
trying to evaluate/execute the resulting code object. It seems that the
global namespace differs depending on where I call parse and eval/exec.

The following code parses a file, compiles and then evaluates the AST.
If I call Python directly on this code, then it works:

        import sys, parser
        ast = parser.suite(open(sys.argv[1]).read())
        code = ast.compile()
        exec(code)

...and it also works this way with Python2.6:

    ast = compile(open(sys.argv[1]).read(), "<AST>",
'exec',_ast.PyCF_ONLY_AST)
    code = compile(ast, "<AST", "exec")
    exec(code)
        
However, if I include that snippet in a different scope (some function
or class), then the namespace that the code object will have differs -
it seems the symbols defined in the AST are not included when executing
the code. For example:

        import sys,parser
        
        def main():
            ast = parser.suite(open(sys.argv[1]).read())
            code = ast.compile()
            exec(code)
        
        if __name__ == "__main__":
          main()

In particular this is a problem if I'm parsing a module with several
functions - none of these functions actually ends up in the scope of the
code object (same behavior with Python2.6 and the PyCF_ONLY_AST
version).

The function "exec" takes parameters for globals and locals, but I have
no idea where to get these dictionaries from the "parser" module. My
guess is that I am misunderstanding something about how Python treats
namespaces. Can anyone help me here?

Thanks,
Gordon





More information about the Python-list mailing list