101 lines
3.3 KiB
Python
101 lines
3.3 KiB
Python
"""
|
|||
|
|
测试:删除 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())
|