Files
insightflow/auto_fix_code.py
AutoFix Bot 9fd1da8fb7 fix: auto-fix code issues (cron)
- 修复重复导入/字段
- 修复异常处理
- 修复PEP8格式问题
- 添加类型注解
2026-03-03 06:03:38 +08:00

236 lines
6.9 KiB
Python

#!/usr/bin/env python3
"""
自动代码修复脚本 - 修复 InsightFlow 项目中的常见问题
"""
import os
import re
def get_python_files(directory):
"""获取目录下所有 Python 文件"""
python_files = []
for root, _, files in os.walk(directory):
for file in files:
if file.endswith('.py'):
python_files.append(os.path.join(root, file))
return python_files
def fix_missing_imports(content, filepath):
"""修复缺失的导入"""
fixes = []
# 检查是否使用了 re 但没有导入
if 're.search(' in content or 're.sub(' in content or 're.match(' in content:
if 'import re' not in content:
# 找到合适的位置添加导入
lines = content.split('\n')
import_idx = 0
for i, line in enumerate(lines):
if line.startswith('import ') or line.startswith('from '):
import_idx = i + 1
lines.insert(import_idx, 'import re')
content = '\n'.join(lines)
fixes.append("添加缺失的 'import re'")
# 检查是否使用了 csv 但没有导入
if 'csv.' in content and 'import csv' not in content:
lines = content.split('\n')
import_idx = 0
for i, line in enumerate(lines):
if line.startswith('import ') or line.startswith('from '):
import_idx = i + 1
lines.insert(import_idx, 'import csv')
content = '\n'.join(lines)
fixes.append("添加缺失的 'import csv'")
# 检查是否使用了 urllib 但没有导入
if 'urllib.' in content and 'import urllib' not in content:
lines = content.split('\n')
import_idx = 0
for i, line in enumerate(lines):
if line.startswith('import ') or line.startswith('from '):
import_idx = i + 1
lines.insert(import_idx, 'import urllib.parse')
content = '\n'.join(lines)
fixes.append("添加缺失的 'import urllib.parse'")
return content, fixes
def fix_bare_excepts(content):
"""修复裸异常捕获"""
fixes = []
# 替换裸 except:
bare_except_pattern = r'except\s*:\s*$'
lines = content.split('\n')
new_lines = []
for line in lines:
if re.match(bare_except_pattern, line.strip()):
# 缩进保持一致
indent = len(line) - len(line.lstrip())
new_line = ' ' * indent + 'except Exception:'
new_lines.append(new_line)
fixes.append(f"修复裸异常捕获: {line.strip()}")
else:
new_lines.append(line)
content = '\n'.join(new_lines)
return content, fixes
def fix_unused_imports(content):
"""修复未使用的导入 - 简单版本"""
fixes = []
# 查找导入语句
import_pattern = r'^from\s+(\S+)\s+import\s+(.+)$'
lines = content.split('\n')
new_lines = []
for line in lines:
match = re.match(import_pattern, line)
if match:
module = match.group(1)
imports = match.group(2)
# 检查每个导入是否被使用
imported_items = [i.strip() for i in imports.split(',')]
used_items = []
for item in imported_items:
# 简单的使用检查
item_name = item.split(' as ')[-1].strip() if ' as ' in item else item.strip()
if item_name in content.replace(line, ''):
used_items.append(item)
else:
fixes.append(f"移除未使用的导入: {item}")
if used_items:
new_lines.append(f"from {module} import {', '.join(used_items)}")
else:
fixes.append(f"移除整行导入: {line.strip()}")
else:
new_lines.append(line)
content = '\n'.join(new_lines)
return content, fixes
def fix_string_formatting(content):
"""统一字符串格式化为 f-string"""
fixes = []
# 修复 .format() 调用
format_pattern = r'["\']([^"\']*)\{([^}]+)\}[^"\']*["\']\.format\(([^)]+)\)'
def replace_format(match):
template = match.group(1) + '{' + match.group(2) + '}'
# 简单替换,实际可能需要更复杂的处理
return f'f"{template}"'
new_content = re.sub(format_pattern, replace_format, content)
if new_content != content:
fixes.append("统一字符串格式化为 f-string")
content = new_content
return content, fixes
def fix_pep8_formatting(content):
"""修复 PEP8 格式问题"""
fixes = []
lines = content.split('\n')
new_lines = []
for line in lines:
original = line
# 修复 E221: multiple spaces before operator
line = re.sub(r'(\w+)\s{2,}=\s', r'\1 = ', line)
# 修复 E251: unexpected spaces around keyword / parameter equals
line = re.sub(r'(\w+)\s*=\s{2,}', r'\1 = ', line)
line = re.sub(r'(\w+)\s{2,}=\s*', r'\1 = ', line)
if line != original:
fixes.append(f"修复 PEP8 格式: {original.strip()[:50]}")
new_lines.append(line)
content = '\n'.join(new_lines)
return content, fixes
def fix_file(filepath):
"""修复单个文件"""
print(f"\n处理文件: {filepath}")
try:
with open(filepath, encoding='utf-8') as f:
content = f.read()
except Exception as e:
print(f" 无法读取文件: {e}")
return []
original_content = content
all_fixes = []
# 应用各种修复
content, fixes = fix_missing_imports(content, filepath)
all_fixes.extend(fixes)
content, fixes = fix_bare_excepts(content)
all_fixes.extend(fixes)
content, fixes = fix_pep8_formatting(content)
all_fixes.extend(fixes)
# 保存修改
if content != original_content:
try:
with open(filepath, 'w', encoding='utf-8') as f:
f.write(content)
print(f" 已修复 {len(all_fixes)} 个问题")
for fix in all_fixes[:5]: # 只显示前5个
print(f" - {fix}")
if len(all_fixes) > 5:
print(f" ... 还有 {len(all_fixes) - 5} 个修复")
except Exception as e:
print(f" 保存文件失败: {e}")
else:
print(" 无需修复")
return all_fixes
def main():
"""主函数"""
base_dir = '/root/.openclaw/workspace/projects/insightflow'
backend_dir = os.path.join(base_dir, 'backend')
print("=" * 60)
print("InsightFlow 代码自动修复工具")
print("=" * 60)
# 获取所有 Python 文件
files = get_python_files(backend_dir)
print(f"\n找到 {len(files)} 个 Python 文件")
total_fixes = 0
fixed_files = 0
for filepath in files:
fixes = fix_file(filepath)
if fixes:
total_fixes += len(fixes)
fixed_files += 1
print("\n" + "=" * 60)
print(f"修复完成: {fixed_files} 个文件, {total_fixes} 个问题")
print("=" * 60)
if __name__ == '__main__':
main()