abstract syntax tree - Python NodeTransformer: how to remove nodes? -


i'm playing around ast manipulations. i'm trying remove nodes input ast. nodetransformer class appropriate tool purpose, think. sadly, doesn't behave expected.

the documetation says:

"the nodetransformer walk ast , use return value of visitor methods replace or remove old node. if return value of visitor method none, node removed location, otherwise replaced return value."

now @ program:

import _ast import ast import sys  #ast transformer class mytransformer(ast.nodetransformer):      def iterate_children(self, node):         """         helper         """         children = ast.iter_child_nodes(node)         c in children:             self.visit(c)      def generic_visit(self, node):         """         default behaviour         """         print("visiting: "+node.__class__.__name__)         self.iterate_children(node)         return node      def visit_for(self, node):         """         nodes: replace nothing         """         print("removing node")         return none    #read source program filename = sys.argv[1] open (filename, "r") myfile:     source = str(myfile.read())  #compile source ast m = compile(source, "<string>", "exec", _ast.pycf_only_ast)  #do ast manipulation t = mytransformer() t.visit(m)  # fix locations m = ast.fix_missing_locations(m)  #visualize resulting ast #p = astprinter() #p.fromast(m)  #execute transformed program print("computing...") codeobj = compile(m, '<string>', 'exec') exec(codeobj) 

here input file:

l = [0, 1, 2, 3]  total = 0  in l:     total +=  print(total) 

and outcome:

visiting: module visiting: assign visiting: name visiting: store visiting: list visiting: num visiting: num visiting: num visiting: num visiting: load visiting: assign visiting: name visiting: store visiting: num removing node visiting: expr visiting: call visiting: name visiting: load visiting: name visiting: load computing... 6 

i expected '0', because loop has been removed. there '6' (=0+1+2+3).

does know why?

python version: 3.2.3

ast illustration

the numbers in ( ) indicate line number in input program. code image drawing not provided here; please ignore "root" node. can see, loop still there.

thanks reading!

update 21.8.:

i posted link question on python mailinglist (python-list@python.org). seems did overwriting. without children visitor, works expected.

entire source code of mytransformer:

class mytransformer(ast.nodetransformer):     def visit_for(self, node):         """         nodes: replace nothing         """         print("removing node")         return none 

no, works correctly because removed self-written generic_visit(). can see in source code of ast.py, nodetransformer child of nodevisitor, has own generic_visit() method. method performs updating of ast nodes , if override method, should know doing for. overriding change logic of nodetransformer.

if still need override generic_visit() (for example print messages visiting: <ast object> when visit node), you have call parent method in generic_visit(). so, method next:

def generic_visit(self, node):         """         printing visit messages         """         super().generic_visit(node)         print("visiting: "+node.__class__.__name__)         self.iterate_children(node)         return node 

the iterate_children() doesn't affect result in case, must removed. forces visitor run over children of each node. generic_visit() runs on nodes. so, iterate_children() visit nodes more once. wastes computing time , may give errors in more complex cases.


Comments

Popular posts from this blog

assembly - 8086 TASM: Illegal Indexing Mode -

Java, LWJGL, OpenGL 1.1, decoding BufferedImage to Bytebuffer and binding to OpenGL across classes -

javascript - addthis share facebook and google+ url -