Reputation: 774
I have a input source code like this
def foo(my_input):
return my_input + 42
and want it to transform like this
def method_name(arg0):
return my_input + 42
The ast node transformer for this purpose is written like this.
class MyRenamer(ast.NodeTransformer):
def __init__(self):
self._arg_count = 0
def visit_FunctionDef(self, node):
node.name = "method_name"
return node
def visit_arg(self, node):
node.arg = "arg_{}".format(self._arg_count)
self._arg_count += 1
return node
but when I call the above transformer like this.
node = ast.parse(code)
renamer = MyRenamer()
node2 = renamer.visit(node)
print(astor.to_source(node2))
The output I get is
def method_name(my_input):
return my_input + 42
Here the argument of the function has not been changed.
Upvotes: 2
Views: 1735
Reputation: 12468
The visitor needs to walk the AST by visiting all children of the currently visited node. The method generic_visit() does that for you, but you have to call it in every visit_... method, or at least for those where children are a possibility.
import ast
import astor
class MyRenamer(ast.NodeTransformer):
def __init__(self):
self._arg_count = 0
def visit_FunctionDef(self, node):
node.name = "method_name"
self.generic_visit(node)
return node
def visit_arg(self, node):
node.arg = "arg_{}".format(self._arg_count)
self._arg_count += 1
self.generic_visit(node)
return node
code = """
def foo(my_input):
return my_input + 42
"""
node = ast.parse(code)
renamer = MyRenamer()
node2 = renamer.visit(node)
print(astor.to_source(node2))
def method_name(arg_0):
return my_input + 42
This gives your expected output, but in a larger context will rename all functions to "method_name", which might not be desired. And there's still the identifier in the function body that presumably also needs to be renamed.
Upvotes: 2