ast manipulation

Discussion in 'Python' started by Tsize, Nov 17, 2009.

  1. Tsize

    Tsize Guest

    Hello,

    I am hoping for a little help. I have been playing with the python
    ast module and have run into
    an issue that I need a little push on. I would like to be able to
    change a specific element in a
    specific node in an ast then compile the resulting ast. Consider the
    simplified example below
    with its output. In this example I would like a way to change a
    specific addition operation. With the NodeTransformer I see how to
    change every addition operator but not how to change a specific one.
    I would like this to work on both the 2.6 and 3.1 branches. Ideally I
    would like to read a file, count the instances of an operation of
    interest and then use an index to make the
    changes.

    I am probably missing something simple but I am lost right now.

    import ast

    class SwitchMinusPlus(ast.NodeTransformer):

    def visit_BinOp(self, node):
    node = self.generic_visit(node)
    if isinstance(node.op, ast.Add):
    node.op = ast.Sub()
    return node

    myfile = open('trivial.py').read()
    print myfile
    tree = compile(myfile, '<string>', 'exec', ast.PyCF_ONLY_AST)
    print ast.dump(tree, annotate_fields=False, include_attributes=False)
    node = SwitchMinusPlus().visit(ast.parse(myfile))
    print ast.dump(node, annotate_fields=False, include_attributes=False)

    Which gives the following output: Note that this code changes the
    addition operator to an
    subtraction operator at the AST level for every instance.

    a = 8
    b = 6
    c = b + a
    d = c + a
    Module([Assign([Name('a', Store())], Num(8)), Assign([Name('b', Store
    ())], Num(6)),
    Assign([Name('c', Store())], BinOp(Name('b', Load()), Add(), Name('a',
    Load()))),
    Assign([Name('d', Store())], BinOp(Name('c', Load()), Add(), Name('a',
    Load())))])

    Module([Assign([Name('a', Store())], Num(8)), Assign([Name('b', Store
    ())], Num(6)),
    Assign([Name('c', Store())], BinOp(Name('b', Load()), Sub(), Name('a',
    Load()))),
    Assign([Name('d', Store())], BinOp(Name('c', Load()), Sub(), Name('a',
    Load())))])

    Thanks in advance,
    Thomas
    Tsize, Nov 17, 2009
    #1
    1. Advertising

  2. Tsize

    Terry Reedy Guest

    Tsize wrote:
    > Hello,
    >
    > I am hoping for a little help. I have been playing with the python
    > ast module and have run into
    > an issue that I need a little push on. I would like to be able to
    > change a specific element in a
    > specific node in an ast then compile the resulting ast.


    If you can identify the specific nodes you want to change, no problem

    > Consider the simplified example below
    > with its output. In this example I would like a way to change a
    > specific addition operation. With the NodeTransformer I see how to
    > change every addition operator but not how to change a specific one.


    Which specific one or one?

    > I would like this to work on both the 2.6 and 3.1 branches. Ideally I
    > would like to read a file, count the instances of an operation of
    > interest and then use an index to make the changes.


    If 'specific one' means number i, great. In not, not.
    >
    > I am probably missing something simple but I am lost right now.


    You have not said what 'specific one' means.
    Nor what your general goal is, why you want to change asts.
    >
    > import ast
    >
    > class SwitchMinusPlus(ast.NodeTransformer):
    >
    > def visit_BinOp(self, node):
    > node = self.generic_visit(node)
    > if isinstance(node.op, ast.Add):


    if isinstance(node.op, ast.Add) and isspecificnode(node):

    > node.op = ast.Sub()
    > return node
    >
    > myfile = open('trivial.py').read()
    > print myfile
    > tree = compile(myfile, '<string>', 'exec', ast.PyCF_ONLY_AST)
    > print ast.dump(tree, annotate_fields=False, include_attributes=False)
    > node = SwitchMinusPlus().visit(ast.parse(myfile))
    > print ast.dump(node, annotate_fields=False, include_attributes=False)
    >
    > Which gives the following output: Note that this code changes the
    > addition operator to an
    > subtraction operator at the AST level for every instance.
    >
    > a = 8
    > b = 6
    > c = b + a
    > d = c + a
    > Module([Assign([Name('a', Store())], Num(8)), Assign([Name('b', Store
    > ())], Num(6)),
    > Assign([Name('c', Store())], BinOp(Name('b', Load()), Add(), Name('a',
    > Load()))),
    > Assign([Name('d', Store())], BinOp(Name('c', Load()), Add(), Name('a',
    > Load())))])
    >
    > Module([Assign([Name('a', Store())], Num(8)), Assign([Name('b', Store
    > ())], Num(6)),
    > Assign([Name('c', Store())], BinOp(Name('b', Load()), Sub(), Name('a',
    > Load()))),
    > Assign([Name('d', Store())], BinOp(Name('c', Load()), Sub(), Name('a',
    > Load())))])
    Terry Reedy, Nov 17, 2009
    #2
    1. Advertising

  3. Tsize

    Tsize Guest

    Terry,

    Thank you for responding. I actually figured out how to do this
    shortly after posting the message. Sorry I wasn't quite clear enough
    in my post, I will try to be a little more explict in the future.
    Just to mention it I want to go to each node in the ast including
    child nodes and change the values. I am making a limited mutation
    analysis program. If it looks generally useful as I get further along
    I will release the code. I did an early prototype that worked on the
    text of the code itself but I thought that using the ast for this
    would be better and maybe a little faster.

    Regards,
    Thomas
    Tsize, Nov 18, 2009
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Arno Seitinger

    cookies between ast and asp.net

    Arno Seitinger, Oct 28, 2004, in forum: ASP .Net
    Replies:
    2
    Views:
    487
    Saravana
    Oct 28, 2004
  2. hlwangz
    Replies:
    0
    Views:
    362
    hlwangz
    Apr 26, 2006
  3. hlwangz

    for-statement in AST

    hlwangz, Apr 26, 2006, in forum: Java
    Replies:
    1
    Views:
    356
    Oliver Wong
    Apr 26, 2006
  4. Oleg Paraschenko

    Python AST as XML

    Oleg Paraschenko, Oct 28, 2004, in forum: XML
    Replies:
    4
    Views:
    451
    Dimitre Novatchev
    Nov 4, 2004
  5. Robert Kern
    Replies:
    6
    Views:
    327
    Duncan Booth
    Oct 20, 2003
Loading...

Share This Page