2

From the given code snippet below, I tried to extract the actual user defined variable name other than the python built-in variable in order to check them agaist my naming convention rules.

ast_example.py

import ast
from pprint import pprint


def main():
    FirstName = "Johnny"
    LastName = "David"
    Variable_One = "Variable1"
    Variable_Two = "Variable2"
    Variable_Three = "Variable3"
    with open("ast_example.py", "r") as source:
        tree = ast.parse(source.read())

    analyzer = Analyzer()
    analyzer.visit(tree)
    analyzer.report()


class Analyzer(ast.NodeVisitor):
    def __init__(self):
        self.stats = {"variable": []}

    def visit_Name(self, node):
        print "Node: ",node.id
        self.stats["variable"].append(node.id)
        self.generic_visit(node)

    def report(self):
        pprint(self.stats)


if __name__ == "__main__":
    main()

However, after I executed the above code snippet, it resulted in not only the variables I wanted but also every python built in variables as well such as self, __name__, open, source, etc which are those I want to exclude.

{'variable': ['FirstName',
              'LastName',
              'Variable_One',
              'Variable_Two',
              'Variable_Three',
              'open',
              'source',
              'tree',
              'ast',
              'source',
              'analyzer',
              'Analyzer',
              'analyzer',
              'tree',
              'analyzer',
              'ast',
              'self',
              'self',
              'self',
              'node',
              'self',
              'node',
              'self',
              'node',
              'self',
              'pprint',
              'self',
              '__name__',
              'main']}

How can I exclude those built in variables? Thanks

2
  • None of self, __name__, open, source are keywords. They're variable names. The keywords here are import, from, def, with, as, class, print and if - and none of them are included in your list, as expected. Commented Jan 20, 2020 at 10:18
  • @ForceBru, ah sorry and thank you for your feedback. I have updated my question to match with that already. I want to exclude those built in from my result list. Thanks Commented Jan 20, 2020 at 10:26

1 Answer 1

2

Instead of visiting Name you might want to visist Assign which is the node that represents assignement.

So the code looks something like this :

def visit_Assign(self, node):
    for target in node.targets:
        self.stats["variable"].append(target.id)
    self.generic_visit(node)

Here targets, represents the multiple values for assignement such as : a, b = 0, 1

ref: python ast doc

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, but I got a strange exception AttributeError: 'Attribute' object has no attribute 'id'. Indeed, by printing target.__dict__ it returned {'ctx': <_ast.Store object at 0x7f699c4d0f90>, 'id': 'FirstName', 'col_offset': 4, 'lineno': 6}, but could not access attrib id even though via ` target.get('id')`. Thanks
I found an error. That was because the last object of target did not contain attrib id. To resolve this, I used try/except, and it worked. Thanks so much :)
Sorry for that, I did not really test the code. You might want to check the type(node) instead of try/except but the idea is here :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.