Coverage for src / renaissance / integrations / python / ast / extractor.py: 77%
31 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-09-09 14:04 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-09-09 14:04 +0000
1from pathlib import Path
3import networkx
5from renaissance.integrations.python.ast.rst_node import PythonRstNode
8class PythonExtractor:
9 graph = networkx.DiGraph()
10 codebase: dict = {}
12 def process(self, file: Path):
13 root = PythonRstNode.load(file)
14 module_name = root.filename.replace("/", ".").replace(".py", "")
15 folder = str(Path(file).parent)
16 self.graph.add_node(folder, type="folder")
17 self.graph.add_edge(folder, module_name, type="contains")
19 for stmt in root:
20 match stmt.ast_type:
21 case "Import":
22 self.graph.add_edge(module_name, stmt.name, type="include")
23 case "ImportFrom":
24 for alias in stmt.node.names:
25 self.graph.add_edge(module_name, f"{stmt.node.module}.{alias.name}", type="include")
26 case "FunctionDef":
27 self.graph.add_edge(module_name, f"{module_name}.{stmt.name}", type="definition")
28 self.graph.add_node(f"{module_name}.{stmt.name}", properties="function")
29 # TODO: convert #, stmt.properties) to graphml
30 case "ClassDef":
31 self.graph.add_edge(module_name, f"{module_name}.{stmt.name}", type="definition")
32 self.graph.add_node(f"{module_name}.{stmt.name}") # convert to args, stmt.properties)
33 case _:
34 pass
36 self.codebase[file] = root
37 # # reconstruct dependencies inside module
38 # tu.lazy_create_refers(root)
39 # self.nodes |= tu._nodes
40 # self.edges |=tu._references
41 # self.edges |= tu._referenced_by
43 def save_graph(self, filename: str):
44 networkx.write_graphml(self.graph, filename)
45 print(f"Graph saved to: {filename}")