modify: 修复 pyarmor 模式无法使用字节码加载的问题
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
"""
|
||||
测试:删除 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())
|
||||
Reference in New Issue
Block a user