Painful?: Using the ast module for metaprogramming
"Martin v. Löwis"
martin at v.loewis.de
Mon Apr 6 07:33:33 CEST 2009
> -If I have the source to a single function definition and I pass it to
> ast.parse, I get back an ast.Module. Why not an ast.FunctionDef?
Because it is easier for processing if you always get the same type of
result. Typically, you don't know what's in the source code, so you
need to parse, then inspect.
> -An ast.Name always has an ast.Load or ast.Store "context" associated
> with it. This is a bit odd, since based on the actual context (what
> the parent of the ast.Name node is) it is always clear whether the
> variable needs to be loaded or stored
It simplifies the interpretation/compilation of the code, by removing
the need to go up in the tree. Notice that just looking at the parent
node would not be sufficient: for
foo[foo] = foo = foo
the various occurrences of foo take all kinds of contexts. Figuring
out whether a specific occurrence is a load or store would be tricky.
> It adds a lot of noise when you're trying to interpret
> trees, and the ast.Load and ast.Store objects themselves don't seem to
> contain any data.
Yes, they are flags only. operator works the same way (taking values
such as Add, Sub, ...); likewise unaryop and cmpop.
> -Why can't orelse for ast.If and ast.While default to empty ?
You want to store None? That would be a type error; orelse is
specified as "stmt*". So it must be a list.
> -Why can't keywords and args for ast.Call default to empty ? Same
> problem as with orelse.
> -Why can't I eval a functiondef to get back a function object?
Because a definition is not an expression. You can only eval
> -The module provides no means to convert an AST back into source code,
> which would be nice for debugging.
> -It would be nice if decorators were passed a function's AST instead
> of a function object.
How could this possibly work? If you run from a pyc file, there will
be no AST available to pass.
More information about the Python-list