"""Source-derived WM recovery case; operate only on a separate working copy.""" import hashlib, json, pathlib, sys import bpy def run(input_path, work_dir): input_path = str(pathlib.Path(input_path).resolve()); assert bpy.app.version == (5, 2, 0) work = pathlib.Path(work_dir).resolve() work.mkdir(parents=True, exist_ok=False) source_sha256 = hashlib.sha256(pathlib.Path(input_path).read_bytes()).hexdigest() assert bpy.ops.wm.open_mainfile(filepath=str(pathlib.Path(input_path).resolve()), load_ui=False, use_scripts=False) == {'FINISHED'} marker = work / 'registered-script.json' key = 'wbv2_native_recovery_script_executed' assert key not in bpy.context.scene text = bpy.data.texts.new('wbv2_native_recovery_trust.py') text.write("import bpy,json\nfrom pathlib import Path\nbpy.context.scene[%r] = True\nPath(%r).write_text(json.dumps({'executed':True,'filepath':bpy.data.filepath}))\n" % (key, str(marker))) text.use_module = True original_images = {image.name: {'pixels': list(image.pixels[:4]), 'size': list(image.size)} for image in bpy.data.images if image.source == 'FILE'} assert original_images and all(image['pixels'] and min(image['size']) > 0 for image in original_images.values()) autosave_dir = work / 'autosave'; autosave_dir.mkdir() previous = (bpy.context.preferences.filepaths.temporary_directory, bpy.context.preferences.filepaths.auto_save_time) try: bpy.context.preferences.filepaths.temporary_directory = str(autosave_dir) bpy.context.preferences.filepaths.auto_save_time = 60 assert bpy.ops.wm.save_as_mainfile(filepath=str(work / 'native-script-trust.blend'), relative_remap=True, check_existing=False) == {'FINISHED'} assert bpy.ops.wm.save_auto_save() == {'FINISHED'} assert not marker.exists() and key not in bpy.context.scene autosaves = sorted(autosave_dir.glob('native-script-trust_*_autosave.blend')) assert len(autosaves) == 1, [str(item) for item in autosaves] autosave_sha256 = hashlib.sha256(autosaves[0].read_bytes()).hexdigest() results = [] for allow in (False, True, False): marker.unlink(missing_ok=True) assert bpy.ops.wm.recover_auto_save(filepath=str(autosaves[0]), use_scripts=allow) == {'FINISHED'} executed = marker.exists() assert executed == allow and bool(bpy.context.scene.get(key, False)) == allow assert pathlib.Path(bpy.data.filepath).resolve() == work / 'native-script-trust.blend' images = {image.name: {'pixels': list(image.pixels[:4]), 'size': list(image.size)} for image in bpy.data.images if image.source == 'FILE'} assert images == original_images assert hashlib.sha256(autosaves[0].read_bytes()).hexdigest() == autosave_sha256 results.append({'useScripts': allow, 'executed': executed, 'sceneMarker': bool(bpy.context.scene.get(key, False)), 'scriptMarker': json.loads(marker.read_text()) if executed else None}) assert hashlib.sha256(pathlib.Path(input_path).read_bytes()).hexdigest() == source_sha256 return {'kind': 'source-derived-native-operator-case', 'platform': sys.platform, 'version': list(bpy.app.version), 'inputSha256': source_sha256, 'autosavePath': str(autosaves[0]), 'autosaveSha256': autosave_sha256, 'workingBlend': bpy.data.filepath, 'results': results, 'images': original_images} finally: bpy.context.preferences.filepaths.temporary_directory, bpy.context.preferences.filepaths.auto_save_time = previous if __name__ == '__main__': import argparse parser = argparse.ArgumentParser() parser.add_argument('--input', required=True) parser.add_argument('--work-dir', required=True) args = parser.parse_args(sys.argv[sys.argv.index('--') + 1:]) print('WBV2_NATIVE_AUTOSAVE_SCRIPT_TRUST', json.dumps(run(args.input, args.work_dir), sort_keys=True))