Spaces:
Sleeping
Sleeping
havinashpatil commited on
Commit Β·
0c0a8ff
1
Parent(s): 27a8fcf
Fix builtin syntax fixer for inline one-line headers and validate TGI fixes
Browse files- server/ai_fixer.py +61 -7
server/ai_fixer.py
CHANGED
|
@@ -83,18 +83,56 @@ Return ONLY the corrected code without any explanation:
|
|
| 83 |
|
| 84 |
# βββ Pattern-Based Fixes βββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 85 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
def fix_syntax_errors(code: str) -> str:
|
| 87 |
"""Try to auto-fix common syntax errors."""
|
| 88 |
lines = code.split('\n')
|
| 89 |
-
|
| 90 |
for line in lines:
|
| 91 |
-
# Fix missing colon on def/class/if/for/while/else/elif/try/except/finally
|
| 92 |
stripped = line.rstrip()
|
| 93 |
if re.match(r'^\s*(def |class |if |elif |else|for |while |try|except|finally)', stripped):
|
| 94 |
-
if
|
| 95 |
-
stripped
|
| 96 |
-
|
| 97 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 98 |
|
| 99 |
|
| 100 |
def fix_wrong_builtins(code: str) -> str:
|
|
@@ -480,7 +518,7 @@ def generate_fix(
|
|
| 480 |
"""
|
| 481 |
if use_tgi:
|
| 482 |
fixed_code = fix_with_tgi(code, tgi_url=tgi_url)
|
| 483 |
-
if fixed_code:
|
| 484 |
# Log complexity vs reward for research tracking
|
| 485 |
complexity = detect_complexity(fixed_code)
|
| 486 |
log_complexity_reward(task_id or "sandbox", reward, complexity, step=0, method="tgi")
|
|
@@ -498,6 +536,22 @@ def generate_fix(
|
|
| 498 |
|
| 499 |
# Fallback: built-in AST pattern fixer
|
| 500 |
fixed_code = apply_all_fixes(code)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 501 |
complexity = detect_complexity(fixed_code)
|
| 502 |
log_complexity_reward(task_id or "sandbox", reward, complexity, step=0, method="builtin")
|
| 503 |
return {
|
|
|
|
| 83 |
|
| 84 |
# βββ Pattern-Based Fixes βββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 85 |
|
| 86 |
+
def _split_header_body(line: str) -> tuple[str, str]:
|
| 87 |
+
"""Split a header line into the statement header and inline body.
|
| 88 |
+
|
| 89 |
+
Example:
|
| 90 |
+
def foo() print('x')
|
| 91 |
+
if x print(x)
|
| 92 |
+
becomes:
|
| 93 |
+
('def foo()', "print('x')")
|
| 94 |
+
"""
|
| 95 |
+
stripped = line.rstrip()
|
| 96 |
+
# Match function or class headers with inline bodies.
|
| 97 |
+
inline_match = re.match(
|
| 98 |
+
r'^(\s*(?:def|class)\s+[A-Za-z_]\w*(?:\([^)]*\))?)(?:\s+(.+))?$',
|
| 99 |
+
stripped,
|
| 100 |
+
)
|
| 101 |
+
if inline_match and inline_match.group(2):
|
| 102 |
+
return inline_match.group(1), inline_match.group(2)
|
| 103 |
+
|
| 104 |
+
# Match conditional and loop headers with inline bodies.
|
| 105 |
+
inline_match = re.match(
|
| 106 |
+
r'^(\s*(?:if|elif|else|for|while|try|except|finally)\b[^:]*?)(?:\s+(.+))?$',
|
| 107 |
+
stripped,
|
| 108 |
+
)
|
| 109 |
+
if inline_match and inline_match.group(2):
|
| 110 |
+
return inline_match.group(1), inline_match.group(2)
|
| 111 |
+
|
| 112 |
+
return stripped, ""
|
| 113 |
+
|
| 114 |
+
|
| 115 |
def fix_syntax_errors(code: str) -> str:
|
| 116 |
"""Try to auto-fix common syntax errors."""
|
| 117 |
lines = code.split('\n')
|
| 118 |
+
fixed_lines: list[str] = []
|
| 119 |
for line in lines:
|
|
|
|
| 120 |
stripped = line.rstrip()
|
| 121 |
if re.match(r'^\s*(def |class |if |elif |else|for |while |try|except|finally)', stripped):
|
| 122 |
+
if stripped.endswith(':') or stripped.endswith('\\') or stripped.endswith(','):
|
| 123 |
+
fixed_lines.append(stripped)
|
| 124 |
+
continue
|
| 125 |
+
|
| 126 |
+
header, inline_body = _split_header_body(stripped)
|
| 127 |
+
if inline_body:
|
| 128 |
+
indent = re.match(r'^(\s*)', line).group(1)
|
| 129 |
+
fixed_lines.append(f"{header}:")
|
| 130 |
+
fixed_lines.append(indent + ' ' + inline_body.strip())
|
| 131 |
+
else:
|
| 132 |
+
fixed_lines.append(stripped + ':')
|
| 133 |
+
else:
|
| 134 |
+
fixed_lines.append(stripped)
|
| 135 |
+
return '\n'.join(fixed_lines)
|
| 136 |
|
| 137 |
|
| 138 |
def fix_wrong_builtins(code: str) -> str:
|
|
|
|
| 518 |
"""
|
| 519 |
if use_tgi:
|
| 520 |
fixed_code = fix_with_tgi(code, tgi_url=tgi_url)
|
| 521 |
+
if fixed_code and validate_code(fixed_code):
|
| 522 |
# Log complexity vs reward for research tracking
|
| 523 |
complexity = detect_complexity(fixed_code)
|
| 524 |
log_complexity_reward(task_id or "sandbox", reward, complexity, step=0, method="tgi")
|
|
|
|
| 536 |
|
| 537 |
# Fallback: built-in AST pattern fixer
|
| 538 |
fixed_code = apply_all_fixes(code)
|
| 539 |
+
if not validate_code(fixed_code):
|
| 540 |
+
# try a second pass with a stricter syntax fixer
|
| 541 |
+
fallback_code = fix_syntax_errors(code)
|
| 542 |
+
if validate_code(fallback_code):
|
| 543 |
+
fixed_code = fallback_code
|
| 544 |
+
else:
|
| 545 |
+
return {
|
| 546 |
+
"fixed_code": code,
|
| 547 |
+
"method": "builtin",
|
| 548 |
+
"success": False,
|
| 549 |
+
"explanation": "Builtin fixer could not produce valid Python code.",
|
| 550 |
+
"error": "Syntax fix failed; please inspect source code manually.",
|
| 551 |
+
"complexity": detect_complexity(code),
|
| 552 |
+
"algo_hint": get_optimization_hint(code),
|
| 553 |
+
}
|
| 554 |
+
|
| 555 |
complexity = detect_complexity(fixed_code)
|
| 556 |
log_complexity_reward(task_id or "sandbox", reward, complexity, step=0, method="builtin")
|
| 557 |
return {
|