I have managed to recursively go over the globals() and gather the functions recursively. Here is the code so far: def extract_functions(self, module_globals, depth=1, parent_name=''): """Extract all functions recursively from modules, starting from depth k down to 0.""" if depth <= 0: # Base case: stop when depth goes below 0 # Return None only for the top-level call, otherwise empty dict for recursion if parent_name == '': return None return {} # Return empty dict for recursive calls to avoid update() errors functions = {} # Add handling for module objects if hasattr(module_globals, '__dict__'): module_globals = module_globals.__dict__ # Now handle dictionary-like objects if not hasattr(module_globals, 'items'): return functions # Create a copy of the dictionary so it's safe if the original dictionary changes items_to_process = list(module_globals.items()) for name, obj in items_to_process: if name == '__builtins__': continue if parent_name == '': cur_name = name else: cur_name = f'{parent_name}.{name}' if inspect.isfunction(obj): substr = '.'.join(cur_name.split('.')[-3:]) if substr in self.name_set: continue self.function_map[substr] = obj functions[substr] = obj # Analyze function body to find calls and imports try: source = inspect.getsource(obj) tree = ast.parse(source) self._analyze_function_body(tree, depth) # Also look for imports within the function self._process_imports_in_function(tree, module_globals) except (OSError, TypeError, SyntaxError): # Continue if source code can't be retrieved or parsed pass elif inspect.ismodule(obj): if name in self.module_list: continue else: self.module_list += [name] # Recursively search in submodule with decremented depth subfunctions = self.extract_functions( obj.__dict__, depth=depth - 1, parent_name=cur_name ) functions.update(subfunctions) return self.function_map when called as obj.extract_functions(globals(),2) it successfully traverses all libraries, (I hope) and returns as a dict. However, when I try to parse the ast Tree from those functions, I cannot access to the other functions' trees, only able to access itself. Is it possible to make this work by making ast trees traversable between functions? Continue reading...