#!/usr/bin/env python3 """ Auto-fix script for InsightFlow code issues """ import re from pathlib import Path def fix_file(filepath): """Fix common issues in a Python file""" with open(filepath, 'r', encoding='utf-8') as f: content = f.read() original = content changes = [] # 1. Fix implicit Optional (RUF013) # Pattern: def func(arg: type = None) -> def func(arg: type | None = None) # Note: implicit_optional_pattern and fix_optional function defined for future use # More careful approach for implicit Optional lines = content.split('\n') new_lines = [] for line in lines: original_line = line # Fix patterns like "metadata: dict = None," if re.search(r':\s*\w+\s*=\s*None', line) and '| None' not in line: # Match parameter definitions match = re.search(r'(\w+)\s*:\s*(\w+(?:\[[^\]]+\])?)\s*=\s*None', line) if match: param_name = match.group(1) param_type = match.group(2) if param_type != 'NoneType': line = line.replace(f'{param_name}: {param_type} = None', f'{param_name}: {param_type} | None = None') if line != original_line: changes.append(f"Fixed implicit Optional: {param_name}") new_lines.append(line) content = '\n'.join(new_lines) # 2. Fix unnecessary assignment before return (RET504) # Note: return_patterns defined for future use pass # Placeholder for future implementation # 3. Fix RUF010 - Use explicit conversion flag # f"...{str(var)}..." -> f"...{var!s}..." content = re.sub(r'\{str\(([^)]+)\)\}', r'{\1!s}', content) content = re.sub(r'\{repr\(([^)]+)\)\}', r'{\1!r}', content) # 4. Fix RET505 - Unnecessary else after return # This is complex, skip for now # 5. Fix PERF401 - List comprehensions (basic cases) # This is complex, skip for now # 6. Fix RUF012 - Mutable default values # Pattern: def func(arg: list = []) -> def func(arg: list = None) with handling content = re.sub(r'(\w+)\s*:\s*list\s*=\s*\[\]', r'\1: list | None = None', content) content = re.sub(r'(\w+)\s*:\s*dict\s*=\s*\{\}', r'\1: dict | None = None', content) # 7. Fix unused imports (basic) # Remove duplicate imports import_lines = re.findall(r'^(import\s+\w+|from\s+\w+\s+import\s+[^\n]+)$', content, re.MULTILINE) seen_imports = set() for imp in import_lines: if imp in seen_imports: content = content.replace(imp + '\n', '\n', 1) changes.append(f"Removed duplicate import: {imp}") seen_imports.add(imp) if content != original: with open(filepath, 'w', encoding='utf-8') as f: f.write(content) return True, changes return False, [] def main(): backend_dir = Path('/root/.openclaw/workspace/projects/insightflow/backend') py_files = list(backend_dir.glob('*.py')) fixed_files = [] all_changes = [] for filepath in py_files: fixed, changes = fix_file(filepath) if fixed: fixed_files.append(filepath.name) all_changes.extend([f"{filepath.name}: {c}" for c in changes]) print(f"Fixed {len(fixed_files)} files:") for f in fixed_files: print(f" - {f}") if all_changes: print("\nChanges made:") for c in all_changes[:20]: print(f" {c}") if __name__ == '__main__': main()