-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser.py
More file actions
71 lines (56 loc) · 2.53 KB
/
Copy pathparser.py
File metadata and controls
71 lines (56 loc) · 2.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import ast
import textwrap
def extract_function_source(file_path: str, function_name: str) -> str:
"""
Parses the file at file_path into an AST, finds the FunctionDef node
matching function_name, and returns its raw source code block.
"""
with open(file_path, "r", encoding="utf-8") as f:
source_code = f.read()
tree = ast.parse(source_code)
for node in ast.walk(tree):
if isinstance(node, ast.FunctionDef) and node.name == function_name:
source_segment = ast.get_source_segment(source_code, node)
if source_segment is not None:
return source_segment
else:
raise ValueError(f"Could not retrieve source segment for function '{function_name}'.")
raise ValueError(f"Function '{function_name}' not found in file '{file_path}'")
def adjust_indentation(code: str, target_indent_spaces: int) -> str:
"""
Dedents the input code first, then indents non-empty lines to match
the target_indent_spaces level.
"""
dedented = textwrap.dedent(code)
return textwrap.indent(dedented, " " * target_indent_spaces)
def replace_function_source(file_path: str, function_name: str, new_source_code: str) -> None:
"""
Locates the FunctionDef node in the source file, calculates its line range,
replaces it with the new healed function code matching the original
indentation level, and writes the updated contents back to disk.
"""
with open(file_path, "r", encoding="utf-8") as f:
source_code = f.read()
tree = ast.parse(source_code)
target_node = None
for node in ast.walk(tree):
if isinstance(node, ast.FunctionDef) and node.name == function_name:
target_node = node
break
if target_node is None:
raise ValueError(f"Function '{function_name}' not found in file '{file_path}'")
# Match indentation of original FunctionDef
indent_spaces = target_node.col_offset
adjusted_new_code = adjust_indentation(new_source_code, indent_spaces)
if not adjusted_new_code.endswith("\n"):
adjusted_new_code += "\n"
# Split original code by lines to do line-range replacement
lines = source_code.splitlines(keepends=True)
# ast line numbers are 1-indexed
start_idx = target_node.lineno - 1
end_idx = target_node.end_lineno
# Perform the in-place line replacement
lines[start_idx:end_idx] = [adjusted_new_code]
# Write the modified code back to the file
with open(file_path, "w", encoding="utf-8") as f:
f.writelines(lines)