Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| """ | |
| patch_plantcv.py - 修补 PlantCV 的 sample_images 函数 | |
| 详细版本,包含错误检查和日志 | |
| """ | |
| import os | |
| import sys | |
| import re | |
| import shutil | |
| def find_plantcv_location(): | |
| """找到 PlantCV 的安装位置""" | |
| try: | |
| import plantcv | |
| plantcv_path = os.path.dirname(plantcv.__file__) | |
| print(f"找到 PlantCV 安装位置: {plantcv_path}") | |
| return plantcv_path | |
| except ImportError: | |
| print("错误: 未找到 PlantCV 安装") | |
| return None | |
| def backup_file(file_path): | |
| """备份原始文件""" | |
| backup_path = file_path + '.backup' | |
| shutil.copy2(file_path, backup_path) | |
| print(f"已备份原始文件到: {backup_path}") | |
| return backup_path | |
| def patch_sample_filenames_function(content): | |
| """修补 sample_filenames 函数""" | |
| # 方法1: 在函数开始处添加类型转换 | |
| pattern = r'(def sample_filenames\([^)]*\):[^{]*?"""[^"]*?""")' | |
| def replacement(match): | |
| original = match.group(1) | |
| # 在 docstring 后添加类型检查 | |
| return original + '\n # 修补:确保 num 参数是整数类型\n num = int(num)' | |
| patched_content = re.sub(pattern, replacement, content, flags=re.DOTALL) | |
| # 如果第一种方法没找到,尝试第二种方法 | |
| if patched_content == content: | |
| # 查找 "if num > len(img_element_array):" 这一行,在前面添加类型转换 | |
| lines = content.split('\n') | |
| new_lines = [] | |
| for i, line in enumerate(lines): | |
| # 在问题行前添加类型转换 | |
| if 'if num > len(img_element_array):' in line: | |
| # 获取当前行的缩进 | |
| indent = len(line) - len(line.lstrip()) | |
| type_check_line = ' ' * indent + 'num = int(num) # 修补:确保 num 是整数' | |
| new_lines.append(type_check_line) | |
| print(f"在第 {i+1} 行前添加类型转换") | |
| new_lines.append(line) | |
| patched_content = '\n'.join(new_lines) | |
| return patched_content | |
| def verify_patch(file_path): | |
| """验证修补是否成功""" | |
| with open(file_path, 'r') as f: | |
| content = f.read() | |
| # 检查是否包含我们的修补代码 | |
| if 'num = int(num)' in content and '修补:确保' in content: | |
| print("✅ 修补验证成功:已添加类型转换代码") | |
| return True | |
| else: | |
| print("❌ 修补验证失败:未找到修补代码") | |
| return False | |
| def patch_plantcv_sample_images(): | |
| """主修补函数""" | |
| print("开始修补 PlantCV sample_images 函数...") | |
| # 1. 找到 PlantCV 位置 | |
| plantcv_path = find_plantcv_location() | |
| if not plantcv_path: | |
| return False | |
| # 2. 定位 sample_images.py 文件 | |
| sample_images_path = os.path.join(plantcv_path, 'utils', 'sample_images.py') | |
| print(f"目标文件: {sample_images_path}") | |
| if not os.path.exists(sample_images_path): | |
| print(f"❌ 错误: 找不到文件 {sample_images_path}") | |
| return False | |
| # 3. 备份原始文件 | |
| try: | |
| backup_path = backup_file(sample_images_path) | |
| except Exception as e: | |
| print(f"❌ 备份失败: {e}") | |
| return False | |
| # 4. 读取原始文件内容 | |
| try: | |
| with open(sample_images_path, 'r', encoding='utf-8') as f: | |
| original_content = f.read() | |
| print(f"✅ 成功读取原始文件,共 {len(original_content.splitlines())} 行") | |
| except Exception as e: | |
| print(f"❌ 读取文件失败: {e}") | |
| return False | |
| # 5. 显示问题代码位置 | |
| lines = original_content.splitlines() | |
| for i, line in enumerate(lines, 1): | |
| if 'if num > len(img_element_array):' in line: | |
| print(f"📍 找到问题代码在第 {i} 行: {line.strip()}") | |
| break | |
| # 6. 应用修补 | |
| try: | |
| patched_content = patch_sample_filenames_function(original_content) | |
| if patched_content == original_content: | |
| print("❌ 修补失败:内容没有改变") | |
| return False | |
| except Exception as e: | |
| print(f"❌ 修补过程出错: {e}") | |
| return False | |
| # 7. 写入修补后的内容 | |
| try: | |
| with open(sample_images_path, 'w', encoding='utf-8') as f: | |
| f.write(patched_content) | |
| print("✅ 修补后的内容已写入文件") | |
| except Exception as e: | |
| print(f"❌ 写入文件失败: {e}") | |
| # 恢复备份 | |
| shutil.copy2(backup_path, sample_images_path) | |
| return False | |
| # 8. 验证修补 | |
| if verify_patch(sample_images_path): | |
| print("🎉 PlantCV sample_images 修补完成!") | |
| # 显示修补摘要 | |
| print("\n📋 修补摘要:") | |
| print(f" - 原始文件: {sample_images_path}") | |
| print(f" - 备份文件: {backup_path}") | |
| print(f" - 修补内容: 在 sample_filenames 函数中添加了 num = int(num)") | |
| return True | |
| else: | |
| print("❌ 修补验证失败,恢复原始文件") | |
| shutil.copy2(backup_path, sample_images_path) | |
| return False | |
| def test_patch(): | |
| """测试修补后的函数""" | |
| print("\n🧪 测试修补后的函数...") | |
| try: | |
| from plantcv.utils import sample_images | |
| print("✅ sample_images 函数导入成功") | |
| # 这里可以添加更多测试 | |
| print("✅ 函数修补测试通过") | |
| return True | |
| except Exception as e: | |
| print(f"❌ 测试失败: {e}") | |
| return False | |
| if __name__ == '__main__': | |
| print("=" * 60) | |
| print("PlantCV sample_images 函数修补工具") | |
| print("=" * 60) | |
| success = patch_plantcv_sample_images() | |
| if success: | |
| test_patch() | |
| print("\n🎉 修补完成!现在可以正常使用 sample_images 函数了。") | |
| else: | |
| print("\n❌ 修补失败!请检查错误信息。") | |
| print("=" * 60) |