""" 测试:删除 PyArmor 模块的源代码后仍能正常加载 """ import sys import os import tempfile import shutil sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "src")) def main(): work_dir = tempfile.mkdtemp(prefix="test_delete_source_") db_path = os.path.join(work_dir, "test.db") try: from module_bank.python_to_sqlite import PythonToSQLite # 1. 创建并打包 PyArmor 模块 print("=" * 60) print("测试:删除源代码后加载 PyArmor 模块") print("=" * 60) print("\n[1/5] 使用 PyArmor 打包模块...") packer = PythonToSQLite(db_path, pyarmor_obfuscate=True) packer.importer.add_module( "mymod", 'def hello(): return "ok"', is_package=False, ) print(" 模块打包完成") # 2. 验证 metadata 中已记录运行时名 print("\n[2/5] 验证 metadata 包含运行时名...") cursor = packer.importer.connection.execute( "SELECT metadata, source_code FROM python_modules WHERE module_name = ?", ("mymod",), ) row = cursor.fetchone() print(f" metadata: {row['metadata']}") assert "pyarmor_runtime" in row["metadata"], "metadata 缺少运行时名" print(" ✓ metadata 正确包含运行时名") assert row["source_code"] is not None, "源代码不应为空" print(" ✓ 源代码存在") # 3. 导入一次(确保能工作) print("\n[3/5] 导入模块(有源代码)...") from module_bank.sqlite_meta_path_finder import SQLiteMetaPathFinder finder = SQLiteMetaPathFinder(db_path) sys.meta_path.insert(0, finder) import importlib mod = importlib.import_module("mymod") assert mod.hello() == "ok" print(f" ✓ 导入成功: hello() = {mod.hello()}") # 4. 删除源代码 print("\n[4/5] 删除源代码...") packer.delete_source_code("mymod") cursor = packer.importer.connection.execute( "SELECT source_code, metadata FROM python_modules WHERE module_name = ?", ("mymod",), ) row = cursor.fetchone() print(f" 删除后 source_code = {row['source_code']}") assert row["source_code"] is None, "源代码未成功删除" print(f" 删除后 metadata = {row['metadata']}") assert row["metadata"] is not None, "metadata 不应为空" print(" ✓ metadata 仍保留") # 5. 重新导入(无源代码) print("\n[5/5] 重新导入模块(无源代码)...") if "mymod" in sys.modules: del sys.modules["mymod"] mod2 = importlib.import_module("mymod") result = mod2.hello() print(f" ✓ 无源代码导入成功: hello() = {result}") assert result == "ok", "模块功能异常" print("\n" + "=" * 60) print("全部通过!删除源代码后仍可正常加载 PyArmor 模块") print("=" * 60) except Exception as e: print(f"\n❌ 测试失败: {e}") import traceback traceback.print_exc() return 1 finally: shutil.rmtree(work_dir, ignore_errors=True) return 0 if __name__ == "__main__": sys.exit(main())