Files
NeoBot/setup_mypyc.py
K2cr2O1 2fafdb004b refactor(permission): 重构权限管理系统,合并管理员管理功能
- 将 admin_manager 功能整合到 permission_manager 中,统一管理
- 采用文件为主、Redis 为辅的架构,确保数据一致性
- 实现原子操作机制,防止数据损坏
- 更新文档说明新的权限管理机制
- 调整相关模块引用和编译配置
2026-01-23 08:37:12 +08:00

118 lines
4.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Mypyc 编译脚本
用于将核心 Python 模块编译为 C 扩展,以提升性能。
使用方法:
python setup_mypyc.py build_ext --inplace
注意:
1. 需要安装 C 编译器 (Windows 上需要 Visual Studio Build Tools, Linux 上需要 GCC)。
2. 编译后的文件 (.pyd 或 .so) 是平台相关的,不能跨平台复制。
3. 建议在部署的目标环境 (Linux) 上运行此脚本。
"""
import os
import sys
import subprocess
# 基础模块列表
# 注意Mypyc 对动态特性支持有限,只选择计算密集或类型明确的模块
modules = [
# 工具模块
'core/utils/json_utils.py', # JSON 处理
'core/utils/executor.py', # 代码执行引擎
'core/utils/singleton.py', # 单例模式基类
'core/utils/exceptions.py', # 自定义异常
'core/utils/logger.py', # 日志模块
# 核心管理模块
'core/managers/command_manager.py', # 指令匹配和分发
'core/managers/permission_manager.py', # 权限管理(包含管理员管理功能)
'core/managers/plugin_manager.py', # 插件管理器
# 核心基础模块
'core/ws.py', # WebSocket 核心
'core/bot.py', # Bot 核心抽象
'core/config_loader.py', # 配置加载
'core/config_models.py', # 配置模型
'core/permission.py', # 权限枚举
# API 基础模块
'core/api/base.py', # API 基础类
# 数据模型(适合编译的高频使用数据类)
'models/message.py', # 消息段模型
'models/sender.py', # 发送者模型
'models/objects.py', # API 响应数据模型
]
# 注意:事件模型文件暂时不编译,因为它们与 mypyc 存在兼容性问题
# mypyc 对某些数据类特性和继承结构的支持有限,会导致运行时错误
# event_models = glob.glob('models/events/*.py')
# event_models = [m for m in event_models if not m.endswith('__init__.py')]
# modules.extend(event_models)
# 确保文件存在
valid_modules = []
for m in modules:
if os.path.exists(m):
valid_modules.append(m)
else:
print(f"Warning: Module {m} not found, skipping.")
if not valid_modules:
print("No valid modules found to compile.")
sys.exit(1)
print(f"Compiling the following modules with mypyc: {valid_modules}")
# 使用 mypyc 命令行工具单独编译每个模块,确保位置正确
success_count = 0
for module_path in valid_modules:
print(f"\nCompiling {module_path}...")
try:
# 直接调用 mypyc 命令行工具
result = subprocess.run(
[sys.executable, '-m', 'mypyc', module_path],
capture_output=True,
text=True,
check=True
)
# 验证编译产物是否在正确位置
module_name = module_path.replace('.py', '')
pyd_path = module_name + '.cp314-win_amd64.pyd'
mypyc_path = module_name + '__mypyc.cp314-win_amd64.pyd'
if os.path.exists(pyd_path):
print(f" ✓ Compiled successfully: {pyd_path}")
success_count += 1
else:
# 检查 build 目录中是否有编译产物
build_pyd_path = os.path.join('build', 'lib.win-amd64-cpython-314', pyd_path)
if os.path.exists(build_pyd_path):
# 如果在 build 目录中,复制到正确位置
os.makedirs(os.path.dirname(pyd_path), exist_ok=True)
import shutil
shutil.copy2(build_pyd_path, pyd_path)
shutil.copy2(os.path.join('build', 'lib.win-amd64-cpython-314', mypyc_path), mypyc_path)
print(f" ✓ Compiled successfully (copied from build directory): {pyd_path}")
success_count += 1
else:
print(" ✗ Compiled but cannot find pyd file")
print(f" Build output:\n{result.stdout[:500]}...")
except subprocess.CalledProcessError as e:
print(f" ✗ Compilation failed with exit code {e.returncode}")
print(f" Error:\n{e.stderr[:500]}...")
except Exception as e:
print(f" ✗ Unexpected error: {e}")
print("\n--- Compilation Summary ---")
print(f"Total modules: {len(valid_modules)}")
print(f"Successfully compiled: {success_count}")
print(f"Failed: {len(valid_modules) - success_count}")
if success_count == 0:
print("No modules were compiled successfully. Exiting with error.")
sys.exit(1)