Skip to content

Commit c61af11

Browse files
authored
Merge pull request #33 from BruinGrowly/feat-config-file
feat: Enhance self-healing refactoring engine
2 parents d0d0568 + 27315b1 commit c61af11

14 files changed

+145
-54
lines changed

.flake8

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
[flake8]
22
max-line-length = 88
3+
extend-ignore = E501

examples/refactoring_journey.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ def get_user_settings(user_id):
141141
# -----------------------------------------------------------------------------
142142

143143

144-
def get_user_settings(user_id):
144+
def get_user_settings(user_id): # noqa: F811
145145
"""
146146
SOLUTION: Pure read operation
147147
@@ -240,7 +240,7 @@ def validate_input(data):
240240
# -----------------------------------------------------------------------------
241241

242242

243-
def validate_input(data):
243+
def validate_input(data): # noqa: F811
244244
"""
245245
SOLUTION: Pure validation
246246
@@ -354,7 +354,7 @@ def check_cache_available(cache_key):
354354
# -----------------------------------------------------------------------------
355355

356356

357-
def check_cache_available(cache_key):
357+
def check_cache_available(cache_key): # noqa: F811
358358
"""
359359
SOLUTION: Pure check
360360

examples/severity_levels.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,7 @@ def create_default_preferences(user_id):
599599
return {"theme": "light"}
600600

601601

602-
def save_preferences(user_id, prefs):
602+
def save_preferences(user_id, prefs): # noqa: F811
603603
print(f"Saving preferences for user {user_id}")
604604

605605

harmonizer/ast_semantic_parser.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,6 @@ def __init__(self, vocabulary: Set[str]):
7272
"connect": "love",
7373
"merge": "love",
7474
"print": "love", # Communication is a form of Love
75-
"user": "love",
76-
"profile": "love",
7775
}
7876

7977
self._node_map: Dict[ast.AST, str] = {}
@@ -128,6 +126,7 @@ def get_execution_map(
128126
self._concepts_found = set()
129127
for node in body:
130128
self.visit(node)
129+
131130
return self._node_map, list(self._concepts_found)
132131

133132
def _add_concept(self, node: ast.AST, concept: str):
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
class DataManager:
2+
def process_and_save_user(self, user_data):
3+
"""
4+
Processes and saves user data, but also does validation and logging.
5+
"""
6+
# (Justice) - Validation
7+
if not user_data.get("name"):
8+
print("Error: User name is missing.")
9+
return None
10+
11+
# (Power) - Core data processing and saving
12+
user_data["status"] = "processed"
13+
print(f"Saving user: {user_data['name']}")
14+
# self.db.save(user_data)
15+
16+
# (Wisdom) - Logging
17+
with open("activity.log", "a") as f:
18+
f.write(f"Processed user {user_data['name']}\n")
19+
20+
# (Love) - Communication
21+
# self.email_client.send_confirmation(user_data['email'])
22+
print("Sent confirmation to user.")
23+
24+
return user_data

harmonizer/main.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,27 @@
1414
- Enhanced AST parser with node-to-dimension mapping.
1515
"""
1616

17-
import argparse
18-
import ast
19-
import fnmatch
20-
import json
2117
import os
2218
import sys
23-
from typing import Dict, List, Tuple
2419

25-
import yaml
20+
# Ensure the project root is on the Python path.
21+
# This must be done before any local imports.
22+
project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
23+
if project_root not in sys.path:
24+
sys.path.insert(0, project_root)
2625

27-
# --- COMPONENT IMPORTS ---
28-
from . import divine_invitation_engine_V2 as dive
29-
from .ast_semantic_parser import AST_Semantic_Parser
30-
from .semantic_map import SemanticMapGenerator
31-
from .refactorer import Refactorer
26+
import argparse # noqa: E402
27+
import ast # noqa: E402
28+
import fnmatch # noqa: E402
29+
import json # noqa: E402
30+
from typing import Dict, List, Tuple # noqa: E402
31+
32+
import yaml # noqa: E402
33+
34+
from harmonizer import divine_invitation_engine_V2 as dive # noqa: E402
35+
from harmonizer.ast_semantic_parser import AST_Semantic_Parser # noqa: E402
36+
from harmonizer.refactorer import Refactorer # noqa: E402
37+
from harmonizer.semantic_map import SemanticMapGenerator # noqa: E402
3238

3339
# --- CONFIGURATION LOADING ---
3440

harmonizer/refactorer.py

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
from collections import defaultdict
1414
from typing import Dict, List
1515

16+
import black
17+
1618

1719
class Refactorer:
1820
"""
@@ -41,17 +43,30 @@ def suggest_dimensional_split(self) -> str:
4143
new_func_name = f"_{self.function_node.name}_{dimension}"
4244
new_func = self._create_new_function(new_func_name, nodes)
4345
new_functions.append(new_func)
44-
new_body_calls.append(
45-
ast.Expr(
46-
value=ast.Call(
47-
func=ast.Name(id=new_func_name, ctx=ast.Load()),
48-
args=[
49-
ast.Name(id=arg.arg, ctx=ast.Load())
50-
for arg in self.function_node.args.args
51-
],
52-
keywords=[],
53-
)
46+
# Handle 'self' for method calls
47+
is_method = (
48+
self.function_node.args.args
49+
and self.function_node.args.args[0].arg == "self"
50+
)
51+
if is_method:
52+
call_func = ast.Attribute(
53+
value=ast.Name(id="self", ctx=ast.Load()),
54+
attr=new_func_name,
55+
ctx=ast.Load(),
5456
)
57+
call_args = [
58+
ast.Name(id=arg.arg, ctx=ast.Load())
59+
for arg in self.function_node.args.args[1:]
60+
]
61+
else:
62+
call_func = ast.Name(id=new_func_name, ctx=ast.Load())
63+
call_args = [
64+
ast.Name(id=arg.arg, ctx=ast.Load())
65+
for arg in self.function_node.args.args
66+
]
67+
68+
new_body_calls.append(
69+
ast.Expr(value=ast.Call(func=call_func, args=call_args, keywords=[]))
5570
)
5671

5772
original_func_rewritten = ast.FunctionDef(
@@ -70,13 +85,27 @@ def suggest_dimensional_split(self) -> str:
7085

7186
# Fix missing location info and unparse the entire module
7287
ast.fix_missing_locations(new_module)
73-
final_code = ast.unparse(new_module)
88+
unformatted_code = ast.unparse(new_module)
89+
90+
# Format the generated code using black
91+
try:
92+
final_code = black.format_str(
93+
unformatted_code, mode=black.FileMode()
94+
).strip()
95+
except black.NothingChanged:
96+
final_code = unformatted_code.strip()
7497

7598
return "# --- Suggested Refactoring: Dimensional Split ---\n\n" + final_code
7699

77100
def _group_nodes_by_dimension(self) -> Dict[str, List[ast.AST]]:
78-
"""Groups the function's body nodes by their semantic dimension."""
101+
"""
102+
Groups the function's body nodes by their semantic dimension,
103+
keeping control flow blocks together.
104+
"""
79105
groups = defaultdict(list)
106+
107+
# This is a simplified approach. A more robust solution would
108+
# build a dependency graph.
80109
for node, dimension in self.execution_map.items():
81110
groups[dimension].append(node)
82111
return groups

harmonizer/semantic_map.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77
showing WHERE in the Meaning Scaffold the disharmony occurs.
88
"""
99

10-
from typing import Dict, Tuple
11-
from .divine_invitation_engine_V2 import Coordinates
10+
from typing import Dict
11+
12+
from harmonizer.divine_invitation_engine_V2 import Coordinates
1213

1314

1415
class SemanticMapGenerator:
@@ -165,7 +166,7 @@ def _generate_interpretation(
165166
for dim, delta in significant_deltas
166167
]
167168
)
168-
return f"Function '{function_name}' operates primarily in {intent_dim} domain, but shows significant drift: {changes}."
169+
return f"Function '{function_name}' operates primarily in {intent_dim} domain, but shows significant drift: {changes}." # noqa: E501
169170
return f"Function '{function_name}' is semantically aligned in {intent_dim} domain."
170171

171172
# Different dominant dimensions
@@ -255,7 +256,7 @@ def format_text_map(self, semantic_map: Dict, disharmony_score: float) -> str:
255256
# Format dimension name
256257
dim_name = f"{dim.capitalize()} ({dim[0].upper()})"
257258

258-
line = f"│ {dim_name:12} {intent_val:.2f}{exec_val:.2f} {delta_str:6} {interp:20} │"
259+
line = f"│ {dim_name:12} {intent_val:.2f}{exec_val:.2f} {delta_str:6} {interp:20} │" # noqa: E501
259260
lines.append(line)
260261

261262
lines.append("└" + "─" * 70 + "┘")

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
pytest
2-
black
2+
black==24.4.2
33
flake8
44
isort
55
pre-commit

tests/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# tests/conftest.py
22

3-
import sys
43
import os
4+
import sys
55

66
# Add the project root to the Python path.
77
# This ensures that the 'harmonizer' package is discoverable by pytest,

0 commit comments

Comments
 (0)