ErisPulse 2.3.3.dev0__py3-none-any.whl → 2.3.4.dev2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ErisPulse/CLI/__init__.py +11 -0
- ErisPulse/CLI/__init__.pyi +13 -0
- ErisPulse/CLI/base.py +52 -0
- ErisPulse/CLI/base.pyi +50 -0
- ErisPulse/CLI/cli.py +224 -0
- ErisPulse/CLI/cli.pyi +80 -0
- ErisPulse/CLI/commands/__init__.py +6 -0
- ErisPulse/CLI/commands/__init__.pyi +12 -0
- ErisPulse/CLI/commands/init.py +395 -0
- ErisPulse/CLI/commands/init.pyi +70 -0
- ErisPulse/CLI/commands/install.py +302 -0
- ErisPulse/CLI/commands/install.pyi +58 -0
- ErisPulse/CLI/commands/list.py +160 -0
- ErisPulse/CLI/commands/list.pyi +44 -0
- ErisPulse/CLI/commands/list_remote.py +123 -0
- ErisPulse/CLI/commands/list_remote.pyi +35 -0
- ErisPulse/CLI/commands/run.py +108 -0
- ErisPulse/CLI/commands/run.pyi +39 -0
- ErisPulse/CLI/commands/self_update.py +232 -0
- ErisPulse/CLI/commands/self_update.pyi +47 -0
- ErisPulse/CLI/commands/uninstall.py +32 -0
- ErisPulse/CLI/commands/uninstall.pyi +24 -0
- ErisPulse/CLI/commands/upgrade.py +56 -0
- ErisPulse/CLI/commands/upgrade.pyi +25 -0
- ErisPulse/CLI/console.pyi +20 -0
- ErisPulse/CLI/registry.py +112 -0
- ErisPulse/CLI/registry.pyi +99 -0
- ErisPulse/{utils → CLI/utils}/__init__.py +2 -6
- ErisPulse/CLI/utils/__init__.pyi +14 -0
- ErisPulse/{utils → CLI/utils}/package_manager.py +146 -20
- ErisPulse/CLI/utils/package_manager.pyi +241 -0
- ErisPulse/{utils → CLI/utils}/reload_handler.py +7 -8
- ErisPulse/CLI/utils/reload_handler.pyi +64 -0
- ErisPulse/Core/Bases/__init__.pyi +14 -0
- ErisPulse/Core/Bases/adapter.py +13 -1
- ErisPulse/Core/Bases/adapter.pyi +140 -0
- ErisPulse/Core/Bases/manager.py +136 -0
- ErisPulse/Core/Bases/manager.pyi +108 -0
- ErisPulse/Core/Bases/module.py +53 -1
- ErisPulse/Core/Bases/module.pyi +95 -0
- ErisPulse/Core/Event/__init__.pyi +26 -0
- ErisPulse/Core/Event/base.pyi +62 -0
- ErisPulse/Core/Event/command.py +6 -1
- ErisPulse/Core/Event/command.pyi +113 -0
- ErisPulse/Core/Event/exceptions.pyi +43 -0
- ErisPulse/Core/Event/message.pyi +93 -0
- ErisPulse/Core/Event/meta.pyi +92 -0
- ErisPulse/Core/Event/notice.pyi +108 -0
- ErisPulse/Core/Event/request.pyi +76 -0
- ErisPulse/Core/Event/wrapper.py +2 -3
- ErisPulse/Core/Event/wrapper.pyi +403 -0
- ErisPulse/Core/__init__.py +16 -13
- ErisPulse/Core/__init__.pyi +16 -0
- ErisPulse/Core/_self_config.py +1 -1
- ErisPulse/Core/_self_config.pyi +72 -0
- ErisPulse/Core/adapter.py +70 -10
- ErisPulse/Core/adapter.pyi +246 -0
- ErisPulse/Core/config.pyi +70 -0
- ErisPulse/Core/exceptions.py +4 -2
- ErisPulse/Core/exceptions.pyi +60 -0
- ErisPulse/Core/lifecycle.py +15 -1
- ErisPulse/Core/lifecycle.pyi +92 -0
- ErisPulse/Core/logger.py +21 -15
- ErisPulse/Core/logger.pyi +169 -0
- ErisPulse/Core/module.py +57 -9
- ErisPulse/Core/module.pyi +189 -0
- ErisPulse/Core/router.py +13 -5
- ErisPulse/Core/router.pyi +120 -0
- ErisPulse/Core/storage.py +94 -256
- ErisPulse/Core/storage.pyi +220 -0
- ErisPulse/__init__.py +35 -1236
- ErisPulse/__init__.pyi +22 -0
- ErisPulse/__main__.py +1 -1
- ErisPulse/__main__.pyi +24 -0
- ErisPulse/loaders/__init__.py +22 -0
- ErisPulse/loaders/__init__.pyi +21 -0
- ErisPulse/loaders/adapter_loader.py +187 -0
- ErisPulse/loaders/adapter_loader.pyi +82 -0
- ErisPulse/loaders/base_loader.py +162 -0
- ErisPulse/loaders/base_loader.pyi +23 -0
- ErisPulse/loaders/initializer.py +150 -0
- ErisPulse/loaders/initializer.pyi +60 -0
- ErisPulse/loaders/module_loader.py +618 -0
- ErisPulse/loaders/module_loader.pyi +179 -0
- ErisPulse/loaders/strategy.py +129 -0
- ErisPulse/loaders/strategy.pyi +90 -0
- ErisPulse/sdk.py +435 -0
- ErisPulse/sdk.pyi +158 -0
- {erispulse-2.3.3.dev0.dist-info → erispulse-2.3.4.dev2.dist-info}/METADATA +6 -20
- erispulse-2.3.4.dev2.dist-info/RECORD +103 -0
- {erispulse-2.3.3.dev0.dist-info → erispulse-2.3.4.dev2.dist-info}/licenses/LICENSE +3 -3
- ErisPulse/Core/ux.py +0 -635
- ErisPulse/utils/cli.py +0 -1097
- erispulse-2.3.3.dev0.dist-info/RECORD +0 -35
- /ErisPulse/{utils → CLI}/console.py +0 -0
- {erispulse-2.3.3.dev0.dist-info → erispulse-2.3.4.dev2.dist-info}/WHEEL +0 -0
- {erispulse-2.3.3.dev0.dist-info → erispulse-2.3.4.dev2.dist-info}/entry_points.txt +0 -0
ErisPulse/Core/lifecycle.py
CHANGED
|
@@ -120,6 +120,15 @@ class LifecycleManager:
|
|
|
120
120
|
:param event: 事件名称
|
|
121
121
|
:param event_data: 事件数据字典
|
|
122
122
|
"""
|
|
123
|
+
# 验证事件类型
|
|
124
|
+
if event_type is None:
|
|
125
|
+
logger.error("事件类型不能为None")
|
|
126
|
+
return
|
|
127
|
+
|
|
128
|
+
if not isinstance(event_type, str) or not event_type:
|
|
129
|
+
logger.error(f"事件类型必须是非空字符串,收到: {event_type}")
|
|
130
|
+
return
|
|
131
|
+
|
|
123
132
|
# 构建完整事件数据
|
|
124
133
|
event_data = {
|
|
125
134
|
"event": event_type,
|
|
@@ -164,4 +173,9 @@ class LifecycleManager:
|
|
|
164
173
|
except Exception as e:
|
|
165
174
|
logger.error(f"生命周期事件处理器执行错误 {event}: {e}")
|
|
166
175
|
|
|
167
|
-
lifecycle = LifecycleManager()
|
|
176
|
+
lifecycle = LifecycleManager()
|
|
177
|
+
|
|
178
|
+
__all__ = [
|
|
179
|
+
"LifecycleManager",
|
|
180
|
+
"lifecycle"
|
|
181
|
+
]
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# type: ignore
|
|
2
|
+
#
|
|
3
|
+
# Auto-generated type stub for lifecycle.py
|
|
4
|
+
# DO NOT EDIT MANUALLY - Generated by generate-type-stubs.py
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
ErisPulse 生命周期管理模块
|
|
9
|
+
|
|
10
|
+
提供统一的生命周期事件管理和触发机制
|
|
11
|
+
|
|
12
|
+
事件标准格式:
|
|
13
|
+
{
|
|
14
|
+
"event": "事件名称", # 必填
|
|
15
|
+
"timestamp": float, # 必填,Unix时间戳
|
|
16
|
+
"data": dict, # 可选,事件相关数据
|
|
17
|
+
"source": str, # 必填,事件来源
|
|
18
|
+
"msg": str # 可选,事件描述
|
|
19
|
+
}
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
import asyncio
|
|
23
|
+
import time
|
|
24
|
+
from typing import Callable, List, Dict, Any
|
|
25
|
+
from .logger import logger
|
|
26
|
+
|
|
27
|
+
class LifecycleManager:
|
|
28
|
+
"""
|
|
29
|
+
生命周期管理器
|
|
30
|
+
|
|
31
|
+
管理SDK的生命周期事件,提供事件注册和触发功能
|
|
32
|
+
支持点式结构事件监听,例如 module.init 可以被 module 监听到
|
|
33
|
+
"""
|
|
34
|
+
def __init__(self: None) -> ...:
|
|
35
|
+
...
|
|
36
|
+
def _validate_event(self: object, event_data: Dict[(str, Any)]) -> bool:
|
|
37
|
+
"""
|
|
38
|
+
验证事件数据格式
|
|
39
|
+
|
|
40
|
+
:param event_data: 事件数据字典
|
|
41
|
+
:return: 是否有效
|
|
42
|
+
"""
|
|
43
|
+
...
|
|
44
|
+
def on(self: object, event: str) -> Callable:
|
|
45
|
+
"""
|
|
46
|
+
注册生命周期事件处理器
|
|
47
|
+
|
|
48
|
+
:param event: 事件名称,支持点式结构如 module.init
|
|
49
|
+
:return: 装饰器函数
|
|
50
|
+
|
|
51
|
+
:raises ValueError: 当事件名无效时抛出
|
|
52
|
+
"""
|
|
53
|
+
...
|
|
54
|
+
def start_timer(self: object, timer_id: str) -> None:
|
|
55
|
+
"""
|
|
56
|
+
开始计时
|
|
57
|
+
|
|
58
|
+
:param timer_id: 计时器ID
|
|
59
|
+
"""
|
|
60
|
+
...
|
|
61
|
+
def get_duration(self: object, timer_id: str) -> float:
|
|
62
|
+
"""
|
|
63
|
+
获取指定计时器的持续时间
|
|
64
|
+
|
|
65
|
+
:param timer_id: 计时器ID
|
|
66
|
+
:return: 持续时间(秒)
|
|
67
|
+
"""
|
|
68
|
+
...
|
|
69
|
+
def stop_timer(self: object, timer_id: str) -> float:
|
|
70
|
+
"""
|
|
71
|
+
停止计时并返回持续时间
|
|
72
|
+
|
|
73
|
+
:param timer_id: 计时器ID
|
|
74
|
+
:return: 持续时间(秒)
|
|
75
|
+
"""
|
|
76
|
+
...
|
|
77
|
+
async def submit_event(self: object, event_type: str) -> None:
|
|
78
|
+
"""
|
|
79
|
+
提交生命周期事件
|
|
80
|
+
|
|
81
|
+
:param event: 事件名称
|
|
82
|
+
:param event_data: 事件数据字典
|
|
83
|
+
"""
|
|
84
|
+
...
|
|
85
|
+
async def _execute_handlers(self: object, event: str, event_data: Dict[(str, Any)]) -> None:
|
|
86
|
+
"""
|
|
87
|
+
执行事件处理器
|
|
88
|
+
|
|
89
|
+
:param event: 事件名称
|
|
90
|
+
:param event_data: 事件数据
|
|
91
|
+
"""
|
|
92
|
+
...
|
ErisPulse/Core/logger.py
CHANGED
|
@@ -91,11 +91,6 @@ class Logger:
|
|
|
91
91
|
:param level: 日志级别(DEBUG/INFO/WARNING/ERROR/CRITICAL)
|
|
92
92
|
:return: bool 设置是否成功
|
|
93
93
|
"""
|
|
94
|
-
from .module import module
|
|
95
|
-
|
|
96
|
-
if not module.is_enabled(module_name):
|
|
97
|
-
self._logger.warning(f"模块 {module_name} 未启用,无法设置日志等级。")
|
|
98
|
-
return False
|
|
99
94
|
level = level.upper()
|
|
100
95
|
if hasattr(logging, level):
|
|
101
96
|
self._module_levels[module_name] = getattr(logging, level)
|
|
@@ -115,19 +110,21 @@ class Logger:
|
|
|
115
110
|
if self._file_handler:
|
|
116
111
|
self._logger.removeHandler(self._file_handler)
|
|
117
112
|
self._file_handler.close()
|
|
113
|
+
self._file_handler = None
|
|
118
114
|
|
|
119
115
|
if isinstance(path, str):
|
|
120
116
|
path = [path]
|
|
121
117
|
|
|
122
118
|
for p in path:
|
|
123
119
|
try:
|
|
124
|
-
|
|
120
|
+
self._file_handler = logging.FileHandler(p, encoding="utf-8")
|
|
125
121
|
# 使用自定义格式化器去除rich markup标签
|
|
126
|
-
|
|
127
|
-
self._logger.addHandler(
|
|
122
|
+
self._file_handler.setFormatter(logging.Formatter("[%(name)s] %(message)s"))
|
|
123
|
+
self._logger.addHandler(self._file_handler)
|
|
128
124
|
return True
|
|
129
125
|
except Exception as e:
|
|
130
126
|
self._logger.error(f"无法设置日志文件 {p}: {e}")
|
|
127
|
+
self._file_handler = None
|
|
131
128
|
return False
|
|
132
129
|
|
|
133
130
|
self._logger.warning("出现极端错误,无法设置日志文件。")
|
|
@@ -140,9 +137,11 @@ class Logger:
|
|
|
140
137
|
:param path: 日志文件路径 Str/List
|
|
141
138
|
:return: bool 设置是否成功
|
|
142
139
|
"""
|
|
143
|
-
|
|
140
|
+
# 检查是否有日志记录
|
|
141
|
+
if not self._logs or all(len(logs) == 0 for logs in self._logs.values()):
|
|
144
142
|
self._logger.warning("没有log记录可供保存。")
|
|
145
143
|
return False
|
|
144
|
+
|
|
146
145
|
if isinstance(path, str):
|
|
147
146
|
path = [path]
|
|
148
147
|
|
|
@@ -162,16 +161,18 @@ class Logger:
|
|
|
162
161
|
self._logger.warning("出现极端错误,无法保存日志。")
|
|
163
162
|
return False
|
|
164
163
|
|
|
165
|
-
def get_logs(self, module_name: str =
|
|
164
|
+
def get_logs(self, module_name: str = None) -> dict:
|
|
166
165
|
"""
|
|
167
166
|
获取日志内容
|
|
168
167
|
|
|
169
|
-
:param module_name (可选):
|
|
168
|
+
:param module_name (可选): 模块名称,None表示获取所有日志
|
|
170
169
|
:return: dict 日志内容
|
|
171
170
|
"""
|
|
172
|
-
if module_name:
|
|
173
|
-
|
|
174
|
-
|
|
171
|
+
if module_name is None:
|
|
172
|
+
# 返回所有日志
|
|
173
|
+
return {k: v.copy() for k, v in self._logs.items()}
|
|
174
|
+
# 返回指定模块的日志
|
|
175
|
+
return {module_name: self._logs.get(module_name, [])}
|
|
175
176
|
|
|
176
177
|
def _save_in_memory(self, ModuleName, msg):
|
|
177
178
|
if ModuleName not in self._logs:
|
|
@@ -226,13 +227,18 @@ class Logger:
|
|
|
226
227
|
except Exception:
|
|
227
228
|
return "Unknown"
|
|
228
229
|
|
|
229
|
-
def get_child(self, child_name: str = "UnknownChild"):
|
|
230
|
+
def get_child(self, child_name: str = "UnknownChild", *, relative: bool = True):
|
|
230
231
|
"""
|
|
231
232
|
获取子日志记录器
|
|
232
233
|
|
|
233
234
|
:param child_name: 子模块名称(可选)
|
|
235
|
+
:param relative: 是否相对于调用者模块(默认True),False表示使用完整名称
|
|
234
236
|
:return: LoggerChild 子日志记录器实例
|
|
235
237
|
"""
|
|
238
|
+
if child_name and not relative:
|
|
239
|
+
# 使用完整的指定名称,不添加前缀
|
|
240
|
+
return LoggerChild(self, child_name)
|
|
241
|
+
|
|
236
242
|
caller_module = self._get_caller()
|
|
237
243
|
if child_name:
|
|
238
244
|
full_module_name = f"{caller_module}.{child_name}"
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# type: ignore
|
|
2
|
+
#
|
|
3
|
+
# Auto-generated type stub for logger.py
|
|
4
|
+
# DO NOT EDIT MANUALLY - Generated by generate-type-stubs.py
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
ErisPulse 日志系统
|
|
9
|
+
|
|
10
|
+
提供模块化日志记录功能,支持多级日志、模块过滤和内存存储。
|
|
11
|
+
|
|
12
|
+
{!--< tips >!--}
|
|
13
|
+
1. 支持按模块设置不同日志级别
|
|
14
|
+
2. 日志可存储在内存中供后续分析
|
|
15
|
+
3. 自动识别调用模块名称
|
|
16
|
+
{!--< /tips >!--}
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
import logging
|
|
20
|
+
import inspect
|
|
21
|
+
import datetime
|
|
22
|
+
from rich.logging import RichHandler
|
|
23
|
+
from rich.console import Console
|
|
24
|
+
|
|
25
|
+
class Logger:
|
|
26
|
+
"""
|
|
27
|
+
日志管理器
|
|
28
|
+
|
|
29
|
+
提供模块化日志记录和存储功能
|
|
30
|
+
|
|
31
|
+
{!--< tips >!--}
|
|
32
|
+
1. 使用set_module_level设置模块日志级别
|
|
33
|
+
2. 使用get_logs获取历史日志
|
|
34
|
+
3. 支持标准日志级别(DEBUG, INFO等)
|
|
35
|
+
{!--< /tips >!--}
|
|
36
|
+
"""
|
|
37
|
+
def __init__(self: None) -> ...:
|
|
38
|
+
...
|
|
39
|
+
def set_memory_limit(self: object, limit: int) -> bool:
|
|
40
|
+
"""
|
|
41
|
+
设置日志内存存储上限
|
|
42
|
+
|
|
43
|
+
:param limit: 日志存储上限
|
|
44
|
+
:return: bool 设置是否成功
|
|
45
|
+
"""
|
|
46
|
+
...
|
|
47
|
+
def set_level(self: object, level: str) -> bool:
|
|
48
|
+
"""
|
|
49
|
+
设置全局日志级别
|
|
50
|
+
|
|
51
|
+
:param level: 日志级别(DEBUG/INFO/WARNING/ERROR/CRITICAL)
|
|
52
|
+
:return: bool 设置是否成功
|
|
53
|
+
"""
|
|
54
|
+
...
|
|
55
|
+
def set_module_level(self: object, module_name: str, level: str) -> bool:
|
|
56
|
+
"""
|
|
57
|
+
设置指定模块日志级别
|
|
58
|
+
|
|
59
|
+
:param module_name: 模块名称
|
|
60
|
+
:param level: 日志级别(DEBUG/INFO/WARNING/ERROR/CRITICAL)
|
|
61
|
+
:return: bool 设置是否成功
|
|
62
|
+
"""
|
|
63
|
+
...
|
|
64
|
+
def set_output_file(self: object, path: ...) -> bool:
|
|
65
|
+
"""
|
|
66
|
+
设置日志输出
|
|
67
|
+
|
|
68
|
+
:param path: 日志文件路径 Str/List
|
|
69
|
+
:return: bool 设置是否成功
|
|
70
|
+
"""
|
|
71
|
+
...
|
|
72
|
+
def save_logs(self: object, path: ...) -> bool:
|
|
73
|
+
"""
|
|
74
|
+
保存所有在内存中记录的日志
|
|
75
|
+
|
|
76
|
+
:param path: 日志文件路径 Str/List
|
|
77
|
+
:return: bool 设置是否成功
|
|
78
|
+
"""
|
|
79
|
+
...
|
|
80
|
+
def get_logs(self: object, module_name: str = ...) -> dict:
|
|
81
|
+
"""
|
|
82
|
+
获取日志内容
|
|
83
|
+
|
|
84
|
+
:param module_name (可选): 模块名称,None表示获取所有日志
|
|
85
|
+
:return: dict 日志内容
|
|
86
|
+
"""
|
|
87
|
+
...
|
|
88
|
+
def _save_in_memory(self: object, ModuleName: ..., msg: ...) -> ...:
|
|
89
|
+
...
|
|
90
|
+
def _setup_config(self: object) -> ...:
|
|
91
|
+
...
|
|
92
|
+
def _get_effective_level(self: object, module_name: ...) -> ...:
|
|
93
|
+
...
|
|
94
|
+
def _get_caller(self: object) -> ...:
|
|
95
|
+
...
|
|
96
|
+
def get_child(self: object, child_name: str = ...) -> ...:
|
|
97
|
+
"""
|
|
98
|
+
获取子日志记录器
|
|
99
|
+
|
|
100
|
+
:param child_name: 子模块名称(可选)
|
|
101
|
+
:param relative: 是否相对于调用者模块(默认True),False表示使用完整名称
|
|
102
|
+
:return: LoggerChild 子日志记录器实例
|
|
103
|
+
"""
|
|
104
|
+
...
|
|
105
|
+
def debug(self: object, msg: ..., *args: ..., **kwargs: ...) -> ...:
|
|
106
|
+
...
|
|
107
|
+
def info(self: object, msg: ..., *args: ..., **kwargs: ...) -> ...:
|
|
108
|
+
...
|
|
109
|
+
def warning(self: object, msg: ..., *args: ..., **kwargs: ...) -> ...:
|
|
110
|
+
...
|
|
111
|
+
def error(self: object, msg: ..., *args: ..., **kwargs: ...) -> ...:
|
|
112
|
+
...
|
|
113
|
+
def critical(self: object, msg: ..., *args: ..., **kwargs: ...) -> ...:
|
|
114
|
+
"""
|
|
115
|
+
记录 CRITICAL 级别日志
|
|
116
|
+
这是最高级别的日志,表示严重的系统错误
|
|
117
|
+
注意:此方法不会触发程序崩溃,仅记录日志
|
|
118
|
+
|
|
119
|
+
{!--< tips >!--}
|
|
120
|
+
1. 这是最高级别的日志,表示严重系统错误
|
|
121
|
+
2. 不会触发程序崩溃,如需终止程序请显式调用 sys.exit()
|
|
122
|
+
3. 会在日志文件中添加 CRITICAL 标记便于后续分析
|
|
123
|
+
{!--< /tips >!--}
|
|
124
|
+
"""
|
|
125
|
+
...
|
|
126
|
+
|
|
127
|
+
class LoggerChild:
|
|
128
|
+
"""
|
|
129
|
+
子日志记录器
|
|
130
|
+
|
|
131
|
+
用于创建具有特定名称的子日志记录器,仅改变模块名称,其他功能全部委托给父日志记录器
|
|
132
|
+
"""
|
|
133
|
+
def __init__(self: None, parent_logger: Logger, name: str) -> ...:
|
|
134
|
+
"""
|
|
135
|
+
初始化子日志记录器
|
|
136
|
+
|
|
137
|
+
:param parent_logger: 父日志记录器实例
|
|
138
|
+
:param name: 子日志记录器名称
|
|
139
|
+
"""
|
|
140
|
+
...
|
|
141
|
+
def debug(self: object, msg: ..., *args: ..., **kwargs: ...) -> ...:
|
|
142
|
+
...
|
|
143
|
+
def info(self: object, msg: ..., *args: ..., **kwargs: ...) -> ...:
|
|
144
|
+
...
|
|
145
|
+
def warning(self: object, msg: ..., *args: ..., **kwargs: ...) -> ...:
|
|
146
|
+
...
|
|
147
|
+
def error(self: object, msg: ..., *args: ..., **kwargs: ...) -> ...:
|
|
148
|
+
...
|
|
149
|
+
def critical(self: object, msg: ..., *args: ..., **kwargs: ...) -> ...:
|
|
150
|
+
"""
|
|
151
|
+
记录 CRITICAL 级别日志
|
|
152
|
+
这是最高级别的日志,表示严重的系统错误
|
|
153
|
+
注意:此方法不会触发程序崩溃,仅记录日志
|
|
154
|
+
|
|
155
|
+
{!--< tips >!--}
|
|
156
|
+
1. 这是最高级别的日志,表示严重系统错误
|
|
157
|
+
2. 不会触发程序崩溃,如需终止程序请显式调用 sys.exit()
|
|
158
|
+
3. 会在日志文件中添加 CRITICAL 标记便于后续分析
|
|
159
|
+
{!--< /tips >!--}
|
|
160
|
+
"""
|
|
161
|
+
...
|
|
162
|
+
def get_child(self: object, child_name: str) -> ...:
|
|
163
|
+
"""
|
|
164
|
+
获取子日志记录器的子记录器
|
|
165
|
+
|
|
166
|
+
:param child_name: 子模块名称
|
|
167
|
+
:return: LoggerChild 子日志记录器实例
|
|
168
|
+
"""
|
|
169
|
+
...
|
ErisPulse/Core/module.py
CHANGED
|
@@ -5,13 +5,15 @@ ErisPulse 模块系统
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import asyncio
|
|
8
|
+
import warnings
|
|
8
9
|
from typing import Any, Dict, List, Type, Optional
|
|
9
10
|
from .logger import logger
|
|
10
11
|
from .config import config
|
|
11
12
|
from .Bases import BaseModule
|
|
12
13
|
from .lifecycle import lifecycle
|
|
14
|
+
from .Bases.manager import ManagerBase
|
|
13
15
|
|
|
14
|
-
class ModuleManager:
|
|
16
|
+
class ModuleManager(ManagerBase):
|
|
15
17
|
"""
|
|
16
18
|
模块管理器
|
|
17
19
|
|
|
@@ -48,9 +50,16 @@ class ModuleManager:
|
|
|
48
50
|
>>> module.register("MyModule", MyModuleClass)
|
|
49
51
|
"""
|
|
50
52
|
# 严格验证模块类,确保继承自BaseModule
|
|
53
|
+
# 先检查是否为类对象
|
|
54
|
+
if not isinstance(module_class, type):
|
|
55
|
+
error_msg = f"模块 {module_name} 的参数必须是类,而不是 {type(module_class).__name__}"
|
|
56
|
+
logger.error(error_msg)
|
|
57
|
+
raise TypeError(error_msg)
|
|
58
|
+
|
|
51
59
|
if not issubclass(module_class, BaseModule):
|
|
52
60
|
warn_msg = f"模块 {module_name} 的类 {module_class.__name__} 没有继承自BaseModule,但我们仍会继续尝试加载这个模块,但请注意这可能引发其他问题"
|
|
53
61
|
logger.warning(warn_msg)
|
|
62
|
+
warnings.warn(warn_msg, UserWarning)
|
|
54
63
|
# error_msg = f"模块 {module_name} 的类 {module_class.__name__} 必须继承自BaseModule"
|
|
55
64
|
# logger.error(error_msg)
|
|
56
65
|
# raise TypeError(error_msg)
|
|
@@ -63,7 +72,9 @@ class ModuleManager:
|
|
|
63
72
|
|
|
64
73
|
# 检查模块名是否已存在
|
|
65
74
|
if module_name in self._module_classes:
|
|
66
|
-
|
|
75
|
+
warn_msg = f"模块 {module_name} 已存在,将覆盖原模块类"
|
|
76
|
+
logger.warning(warn_msg)
|
|
77
|
+
warnings.warn(warn_msg, UserWarning)
|
|
67
78
|
|
|
68
79
|
self._module_classes[module_name] = module_class
|
|
69
80
|
if module_info:
|
|
@@ -189,14 +200,15 @@ class ModuleManager:
|
|
|
189
200
|
:param module_name: 模块名称
|
|
190
201
|
:return: 是否卸载成功
|
|
191
202
|
"""
|
|
203
|
+
# 模块未加载,返回 True(表示没有需要卸载的模块,这不是错误)
|
|
192
204
|
if module_name not in self._loaded_modules:
|
|
193
205
|
logger.warning(f"模块 {module_name} 未加载")
|
|
194
|
-
return
|
|
206
|
+
return True
|
|
195
207
|
|
|
196
208
|
try:
|
|
197
209
|
# 调用模块的on_unload卸载方法
|
|
198
|
-
instance = self._modules
|
|
199
|
-
if hasattr(instance, 'on_unload'):
|
|
210
|
+
instance = self._modules.get(module_name)
|
|
211
|
+
if instance and hasattr(instance, 'on_unload'):
|
|
200
212
|
try:
|
|
201
213
|
if asyncio.iscoroutinefunction(instance.on_unload):
|
|
202
214
|
await instance.on_unload({"module_name": module_name})
|
|
@@ -204,9 +216,9 @@ class ModuleManager:
|
|
|
204
216
|
instance.on_unload({"module_name": module_name})
|
|
205
217
|
except Exception as e:
|
|
206
218
|
logger.error(f"模块 {module_name} on_unload 方法执行失败: {e}")
|
|
207
|
-
|
|
219
|
+
|
|
208
220
|
# 清理缓存
|
|
209
|
-
del self._modules[module_name]
|
|
221
|
+
del self._modules[module_name]
|
|
210
222
|
self._loaded_modules.discard(module_name)
|
|
211
223
|
|
|
212
224
|
logger.info(f"模块 {module_name} 卸载成功")
|
|
@@ -334,13 +346,49 @@ class ModuleManager:
|
|
|
334
346
|
self._loaded_modules.discard(module_name)
|
|
335
347
|
return True
|
|
336
348
|
|
|
349
|
+
def unregister(self, module_name: str) -> bool:
|
|
350
|
+
"""
|
|
351
|
+
取消注册模块
|
|
352
|
+
|
|
353
|
+
:param module_name: 模块名称
|
|
354
|
+
:return: 是否取消成功
|
|
355
|
+
|
|
356
|
+
{!--< internal-use >!--}
|
|
357
|
+
注意:此方法仅取消注册,不卸载已加载的模块
|
|
358
|
+
{!--< /internal-use >!--}
|
|
359
|
+
"""
|
|
360
|
+
if module_name not in self._module_classes:
|
|
361
|
+
logger.warning(f"模块 {module_name} 未注册")
|
|
362
|
+
return False
|
|
363
|
+
|
|
364
|
+
# 移除模块类
|
|
365
|
+
self._module_classes.pop(module_name)
|
|
366
|
+
|
|
367
|
+
# 移除模块信息
|
|
368
|
+
if module_name in self._module_info:
|
|
369
|
+
self._module_info.pop(module_name)
|
|
370
|
+
|
|
371
|
+
logger.info(f"模块 {module_name} 已取消注册")
|
|
372
|
+
return True
|
|
373
|
+
|
|
374
|
+
def list_items(self) -> Dict[str, bool]:
|
|
375
|
+
"""
|
|
376
|
+
列出所有模块状态
|
|
377
|
+
|
|
378
|
+
:return: {模块名: 是否启用} 字典
|
|
379
|
+
"""
|
|
380
|
+
return config.getConfig("ErisPulse.modules.status", {})
|
|
381
|
+
|
|
382
|
+
# 兼容性方法 - 保持向后兼容
|
|
337
383
|
def list_modules(self) -> Dict[str, bool]:
|
|
338
384
|
"""
|
|
339
385
|
列出所有模块状态
|
|
340
386
|
|
|
387
|
+
{!--< deprecated >!--} 请使用 list_items() 代替
|
|
388
|
+
|
|
341
389
|
:return: [Dict[str, bool]] 模块状态字典
|
|
342
390
|
"""
|
|
343
|
-
return
|
|
391
|
+
return self.list_items()
|
|
344
392
|
|
|
345
393
|
# ==================== 工具方法 ====================
|
|
346
394
|
|
|
@@ -370,4 +418,4 @@ module = ModuleManager()
|
|
|
370
418
|
|
|
371
419
|
__all__ = [
|
|
372
420
|
"module"
|
|
373
|
-
]
|
|
421
|
+
]
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# type: ignore
|
|
2
|
+
#
|
|
3
|
+
# Auto-generated type stub for module.py
|
|
4
|
+
# DO NOT EDIT MANUALLY - Generated by generate-type-stubs.py
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
ErisPulse 模块系统
|
|
9
|
+
|
|
10
|
+
提供标准化的模块注册、加载和管理功能,与适配器系统保持一致的设计模式
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import asyncio
|
|
14
|
+
import warnings
|
|
15
|
+
from typing import Any, Dict, List, Type, Optional
|
|
16
|
+
from .logger import logger
|
|
17
|
+
from .config import config
|
|
18
|
+
from .Bases import BaseModule
|
|
19
|
+
from .lifecycle import lifecycle
|
|
20
|
+
from .Bases.manager import ManagerBase
|
|
21
|
+
|
|
22
|
+
class ModuleManager(ManagerBase):
|
|
23
|
+
"""
|
|
24
|
+
模块管理器
|
|
25
|
+
|
|
26
|
+
提供标准化的模块注册、加载和管理功能,模仿适配器管理器的模式
|
|
27
|
+
|
|
28
|
+
{!--< tips >!--}
|
|
29
|
+
1. 使用register方法注册模块类
|
|
30
|
+
2. 使用load/unload方法加载/卸载模块
|
|
31
|
+
3. 通过get方法获取模块实例
|
|
32
|
+
{!--< /tips >!--}
|
|
33
|
+
"""
|
|
34
|
+
def __init__(self: None) -> ...:
|
|
35
|
+
...
|
|
36
|
+
def register(self: object, module_name: str, module_class: Type, module_info: Optional[Dict] = ...) -> bool:
|
|
37
|
+
"""
|
|
38
|
+
注册模块类
|
|
39
|
+
|
|
40
|
+
:param module_name: 模块名称
|
|
41
|
+
:param module_class: 模块类
|
|
42
|
+
:param module_info: 模块信息
|
|
43
|
+
:return: 是否注册成功
|
|
44
|
+
|
|
45
|
+
:raises TypeError: 当模块类无效时抛出
|
|
46
|
+
|
|
47
|
+
:example:
|
|
48
|
+
>>> module.register("MyModule", MyModuleClass)
|
|
49
|
+
"""
|
|
50
|
+
...
|
|
51
|
+
async def load(self: object, module_name: str) -> bool:
|
|
52
|
+
"""
|
|
53
|
+
加载指定模块(标准化加载逻辑)
|
|
54
|
+
|
|
55
|
+
:param module_name: 模块名称
|
|
56
|
+
:return: 是否加载成功
|
|
57
|
+
|
|
58
|
+
:example:
|
|
59
|
+
>>> await module.load("MyModule")
|
|
60
|
+
"""
|
|
61
|
+
...
|
|
62
|
+
async def unload(self: object, module_name: str = ...) -> bool:
|
|
63
|
+
"""
|
|
64
|
+
卸载指定模块或所有模块
|
|
65
|
+
|
|
66
|
+
:param module_name: 模块名称,如果为None则卸载所有模块
|
|
67
|
+
:return: 是否卸载成功
|
|
68
|
+
|
|
69
|
+
:example:
|
|
70
|
+
>>> await module.unload("MyModule")
|
|
71
|
+
>>> await module.unload() # 卸载所有模块
|
|
72
|
+
"""
|
|
73
|
+
...
|
|
74
|
+
def get(self: object, module_name: str) -> Any:
|
|
75
|
+
"""
|
|
76
|
+
获取模块实例
|
|
77
|
+
|
|
78
|
+
:param module_name: 模块名称
|
|
79
|
+
:return: 模块实例或None
|
|
80
|
+
|
|
81
|
+
:example:
|
|
82
|
+
>>> my_module = module.get("MyModule")
|
|
83
|
+
"""
|
|
84
|
+
...
|
|
85
|
+
def exists(self: object, module_name: str) -> bool:
|
|
86
|
+
"""
|
|
87
|
+
检查模块是否存在(在配置中注册)
|
|
88
|
+
|
|
89
|
+
:param module_name: [str] 模块名称
|
|
90
|
+
:return: [bool] 模块是否存在
|
|
91
|
+
"""
|
|
92
|
+
...
|
|
93
|
+
def is_loaded(self: object, module_name: str) -> bool:
|
|
94
|
+
"""
|
|
95
|
+
检查模块是否已加载
|
|
96
|
+
|
|
97
|
+
:param module_name: 模块名称
|
|
98
|
+
:return: 模块是否已加载
|
|
99
|
+
|
|
100
|
+
:example:
|
|
101
|
+
>>> if module.is_loaded("MyModule"): ...
|
|
102
|
+
"""
|
|
103
|
+
...
|
|
104
|
+
def list_registered(self: object) -> List[str]:
|
|
105
|
+
"""
|
|
106
|
+
列出所有已注册的模块
|
|
107
|
+
|
|
108
|
+
:return: 模块名称列表
|
|
109
|
+
|
|
110
|
+
:example:
|
|
111
|
+
>>> registered = module.list_registered()
|
|
112
|
+
"""
|
|
113
|
+
...
|
|
114
|
+
def list_loaded(self: object) -> List[str]:
|
|
115
|
+
"""
|
|
116
|
+
列出所有已加载的模块
|
|
117
|
+
|
|
118
|
+
:return: 模块名称列表
|
|
119
|
+
|
|
120
|
+
:example:
|
|
121
|
+
>>> loaded = module.list_loaded()
|
|
122
|
+
"""
|
|
123
|
+
...
|
|
124
|
+
def _config_register(self: object, module_name: str, enabled: bool = ...) -> bool:
|
|
125
|
+
"""
|
|
126
|
+
注册新模块信息
|
|
127
|
+
|
|
128
|
+
:param module_name: [str] 模块名称
|
|
129
|
+
:param enabled: [bool] 是否启用模块
|
|
130
|
+
:return: [bool] 操作是否成功
|
|
131
|
+
"""
|
|
132
|
+
...
|
|
133
|
+
def is_enabled(self: object, module_name: str) -> bool:
|
|
134
|
+
"""
|
|
135
|
+
检查模块是否启用
|
|
136
|
+
|
|
137
|
+
:param module_name: [str] 模块名称
|
|
138
|
+
:return: [bool] 模块是否启用
|
|
139
|
+
"""
|
|
140
|
+
...
|
|
141
|
+
def enable(self: object, module_name: str) -> bool:
|
|
142
|
+
"""
|
|
143
|
+
启用模块
|
|
144
|
+
|
|
145
|
+
:param module_name: [str] 模块名称
|
|
146
|
+
:return: [bool] 操作是否成功
|
|
147
|
+
"""
|
|
148
|
+
...
|
|
149
|
+
def disable(self: object, module_name: str) -> bool:
|
|
150
|
+
"""
|
|
151
|
+
禁用模块
|
|
152
|
+
|
|
153
|
+
:param module_name: [str] 模块名称
|
|
154
|
+
:return: [bool] 操作是否成功
|
|
155
|
+
"""
|
|
156
|
+
...
|
|
157
|
+
def list_items(self: object) -> Dict[(str, bool)]:
|
|
158
|
+
"""
|
|
159
|
+
列出所有模块状态
|
|
160
|
+
|
|
161
|
+
:return: {模块名: 是否启用} 字典
|
|
162
|
+
"""
|
|
163
|
+
...
|
|
164
|
+
def list_modules(self: object) -> Dict[(str, bool)]:
|
|
165
|
+
"""
|
|
166
|
+
列出所有模块状态
|
|
167
|
+
|
|
168
|
+
{!--< deprecated >!--} 请使用 list_items() 代替
|
|
169
|
+
|
|
170
|
+
:return: [Dict[str, bool]] 模块状态字典
|
|
171
|
+
"""
|
|
172
|
+
...
|
|
173
|
+
def __getattr__(self: object, module_name: str) -> Any:
|
|
174
|
+
"""
|
|
175
|
+
通过属性访问获取模块实例
|
|
176
|
+
|
|
177
|
+
:param module_name: [str] 模块名称
|
|
178
|
+
:return: [Any] 模块实例
|
|
179
|
+
:raises AttributeError: 当模块不存在或未启用时
|
|
180
|
+
"""
|
|
181
|
+
...
|
|
182
|
+
def __contains__(self: object, module_name: str) -> bool:
|
|
183
|
+
"""
|
|
184
|
+
检查模块是否存在且处于启用状态
|
|
185
|
+
|
|
186
|
+
:param module_name: [str] 模块名称
|
|
187
|
+
:return: [bool] 模块是否存在且启用
|
|
188
|
+
"""
|
|
189
|
+
...
|