4

I have a python project which doesn't follow naming convention i.e "variables and function names are snake_case" they are written using C# convention "CamelCase". I've tried using RegEx To change these names but the results were not accurate. Here I used AST tree in order to change the names. I couldn't find any useful example to help me understand how to change nodes in the AST tree and then rewrite it back.

The final code I tried is the following, where I tried to change the names to lower case first

    import ast
    import astunparse


    def byter(src):
       
        class RewriteStr(ast.NodeTransformer):
            def generic_visit(self, node):
                print("inside generic", type(node).__name__)

                ast.NodeVisitor.generic_visit(self, node)
                return node

            def visit_Str(self, node):
                print("visiting a str node", type(node).__name__)
                return ast.Bytes(node.s.encode('ascii'))

            def visit_FunctionDef(self, node):
                print("inside def", type(node).__name__)
                return ast.FunctionDef(name=node.name.lower())

            def visit_Call(self, node):
                print("inside call", type(node).__name__)
                if hasattr(node.func, "value"):
                    print(ast.dump(node.func.value))
                    return ast.copy_location(ast.Call(func=ast.Name(id=node.func.value.id.lower())), node)

            def visit_Name(self, node):
                print("name ", type(node).__name__, ast.dump(ast.Name(id=node.id.lower(), ctx=node.ctx)))
                return ast.copy_location(ast.Name(id=node.id.lower(), ctx=node.ctx), node)

        tree = ast.parse(src)
        tree = RewriteStr().visit(tree)
        ast.fix_missing_locations(tree)
        # get back the source code


        # get a pretty-printed dump of the AST


        print(ast.dump(tree))
        print(astunparse.unparse(tree))
        out = open("C:\\Users\\pc1\\Desktop\\output.txt", "w", encoding="UTF-8")


    tree = open("C:\\Users\\pc1\\Desktop\\sampl.py", encoding="UTF-8").read()
    byter(tree)

input file was

    import FooFOo

    DATA = open('file')                     # a function call

    FooFoo.bar(arg=data)                       # a function call

    FooFoo.bar(arg=foo.meow(foo.z(arg=data)))  # three function calls

    FooFoo.WooF(foo.x.y(arg=data))
    def FunC():
        print("foo foo")

When I print the tree after the transformer finishes the nodes are not changed. Am I doing this wrong from the start? Is that a right usage of AST tree? Is there a way to rename functions and vars in python code other than this which is more accurate and less painfull ?

Community
  • 1
  • 1
Ali.Wassouf
  • 309
  • 4
  • 21
  • Why don't you use existing refactoring features present in nearly every modern IDE? Please see https://stackoverflow.com/questions/28796/what-refactoring-tools-do-you-use-for-python – Abdul Rauf Sep 22 '17 at 10:43
  • Possible duplicate of [PyCharm - how to rename all identifiers in project to snake\_case automatically?](https://stackoverflow.com/questions/45259141/pycharm-how-to-rename-all-identifiers-in-project-to-snake-case-automatically) – Georgy May 21 '19 at 09:55

1 Answers1

0

Though you've likely moved on from this project since September, you should take a look at Rope for Python refactoring which will be both more accurate and less painful than an AST tree.

As was mentioned in the comments: various IDEs have their own functionality for refactoring and it's usually a reasonable decision to go with what is built in. If you're using emacs or vim, it's possible to use Rope directly.

Seth Rothschild
  • 384
  • 1
  • 14