storing all function body from txt file in dictionary in python

Question:

I’m trying to do code analyzer app and i have a txt file that contains a python code and my goal now is to save all functions in this txt file in dictionary in the class, but i don’t have any idea how can i do it

at first i create class that name is class CodeAnalyzer:

def __init__(self, file):
    self.file = file
    self.file_string = ""
    self.file_func= {}
    self.errors = {}

and i want to save function in self.file_func= {}

this is process step, every method should return key and value added to attributes

def process_file(self):
        for i, line in enumerate(self.file):
            self.file_string += line
            self.check_divide_by_zero(i, line)
            self.check_parameters_num(i, line)

This what i tried to do but ie’s failed :

def store_function(self,i,line):
            if(line.startswith('def')):
                self.file_func.setdefault(i,[]).append((self.file_string[file_string.index(':') ,:]))

Any one have an Idea or help on it ?

Asked By: Talia Dianal

||

Answers:

You can just use exec() with it’s globals() dict set to your class instance’s namespace.

class CodeAnalyzer:
  def __init__(self,file):
    # Read a string from the file
    f=open(file)
    t=f.read()
    f.close()

    #Populate the namespace dictionary by executing the code in the file
    self.namespace={}#this includes all declarations of functions, variables and classes
    exec(t,self.namespace)#this means that when variables are declared, they use the class instance's attributes dictionary as their global namespace

    #Filter the namespace dict based on the contents
    self.functions={i:self.namespace[i] for i in self.namespace if isinstance(i,type(lambda:0))}#type(lambda:0) is just FunctionType
    self.classes={i:self.namespace[i] for i in self.namespace if isinstance(i,type)}#all classes are instances of type
    self.variables={i:self.namespace[i] for i in self.namespace if i not in self.functions|self.classes}#everything else, using dictionary merge

Feel free to comment on this answer if you have further questions.

Answered By: Mous

I think the isinstance check should be

self.functions={i:self.namespace[i] for i in self.namespace if isinstance(self.namespace[i],type(lambda:0))}

we want to test the i-th element of the self.namespace, not the value of i.

Answered By: Peter Roche