ErisPulse 2.3.4.dev2__py3-none-any.whl → 2.3.4.dev114514__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.
Files changed (40) hide show
  1. ErisPulse/Core/Bases/module.py +1 -53
  2. ErisPulse/Core/Bases/module.pyi +0 -43
  3. ErisPulse/Core/Event/command.py +1 -6
  4. ErisPulse/Core/_self_config.py +1 -1
  5. ErisPulse/Core/adapter.py +10 -70
  6. ErisPulse/Core/adapter.pyi +1 -18
  7. ErisPulse/Core/exceptions.py +2 -4
  8. ErisPulse/Core/lifecycle.py +0 -9
  9. ErisPulse/Core/logger.py +15 -21
  10. ErisPulse/Core/logger.pyi +1 -2
  11. ErisPulse/Core/module.py +9 -57
  12. ErisPulse/Core/module.pyi +1 -12
  13. ErisPulse/Core/router.py +5 -13
  14. ErisPulse/Core/storage.py +256 -94
  15. ErisPulse/Core/storage.pyi +66 -13
  16. ErisPulse/__init__.py +1237 -35
  17. ErisPulse/__init__.pyi +290 -3
  18. ErisPulse/sdk_protocol.py +143 -0
  19. ErisPulse/sdk_protocol.pyi +97 -0
  20. {erispulse-2.3.4.dev2.dist-info → erispulse-2.3.4.dev114514.dist-info}/METADATA +1 -1
  21. {erispulse-2.3.4.dev2.dist-info → erispulse-2.3.4.dev114514.dist-info}/RECORD +24 -38
  22. ErisPulse/Core/Bases/manager.py +0 -136
  23. ErisPulse/Core/Bases/manager.pyi +0 -108
  24. ErisPulse/loaders/__init__.py +0 -22
  25. ErisPulse/loaders/__init__.pyi +0 -21
  26. ErisPulse/loaders/adapter_loader.py +0 -187
  27. ErisPulse/loaders/adapter_loader.pyi +0 -82
  28. ErisPulse/loaders/base_loader.py +0 -162
  29. ErisPulse/loaders/base_loader.pyi +0 -23
  30. ErisPulse/loaders/initializer.py +0 -150
  31. ErisPulse/loaders/initializer.pyi +0 -60
  32. ErisPulse/loaders/module_loader.py +0 -618
  33. ErisPulse/loaders/module_loader.pyi +0 -179
  34. ErisPulse/loaders/strategy.py +0 -129
  35. ErisPulse/loaders/strategy.pyi +0 -90
  36. ErisPulse/sdk.py +0 -435
  37. ErisPulse/sdk.pyi +0 -158
  38. {erispulse-2.3.4.dev2.dist-info → erispulse-2.3.4.dev114514.dist-info}/WHEEL +0 -0
  39. {erispulse-2.3.4.dev2.dist-info → erispulse-2.3.4.dev114514.dist-info}/entry_points.txt +0 -0
  40. {erispulse-2.3.4.dev2.dist-info → erispulse-2.3.4.dev114514.dist-info}/licenses/LICENSE +0 -0
ErisPulse/__init__.py CHANGED
@@ -10,46 +10,1248 @@ ErisPulse SDK 主模块
10
10
  {!--< /tips >!--}
11
11
  """
12
12
 
13
+ import os
14
+ import sys
15
+ import types
16
+ import importlib
17
+ import asyncio
18
+ import inspect
13
19
  import importlib.metadata
20
+ from typing import Dict, List, Tuple, Type, Any, TYPE_CHECKING
21
+ from pathlib import Path
14
22
 
15
- # 导入核心模块
16
- from .Core import (
17
- Event,
18
- lifecycle,
19
- logger,
20
- exceptions,
21
- storage,
22
- env,
23
- config,
24
- adapter,
25
- AdapterFather,
26
- BaseAdapter,
27
- SendDSL,
28
- module,
29
- router,
30
- adapter_server,
31
- )
32
-
33
- # 导入实际的SDK对象
34
- from .sdk import sdk
35
-
36
- # 导入懒加载模块类
37
- from .loaders.module_loader import LazyModule
38
-
39
- # 版本信息
40
- __version__ = "UnknownVersion"
41
- __author__ = "ErisPulse"
23
+ # 类型检查时导入 Protocol,避免运行时循环导入
24
+ if TYPE_CHECKING:
25
+ from .sdk_protocol import SDKProtocol
26
+
27
+ # BaseModules: SDK核心模块
28
+ # 事件处理模块
29
+ from .Core import Event
30
+ # 基础设施
31
+ from .Core import lifecycle, logger, exceptions
32
+ # 存储和配置相关
33
+ from .Core import storage, env, config
34
+ # 适配器相关
35
+ from .Core import adapter, AdapterFather, BaseAdapter, SendDSL
36
+ # 模块相关
37
+ from .Core import module
38
+ # 路由相关
39
+ from .Core import router, adapter_server
40
+
41
+ # SDK统一对外接口
42
+ sdk: 'SDKProtocol' = types.ModuleType('sdk') # type: ignore[assignment]
42
43
 
43
44
  try:
44
45
  __version__ = importlib.metadata.version('ErisPulse')
45
46
  except importlib.metadata.PackageNotFoundError:
46
- pass
47
+ logger.critical("未找到ErisPulse版本信息,请检查是否正确安装ErisPulse")
48
+ __author__ = "ErisPulse"
49
+
50
+ logger.debug("ErisPulse 正在挂载SDK核心模块...")
51
+
52
+ BaseModules = {
53
+ "Event" : Event,
54
+
55
+ "lifecycle" : lifecycle,
56
+ "logger" : logger,
57
+ "exceptions" : exceptions,
58
+
59
+ "storage" : storage,
60
+ "env" : env,
61
+ "config" : config,
62
+
63
+ "adapter" : adapter,
64
+ "AdapterFather" : AdapterFather,
65
+ "BaseAdapter" : BaseAdapter,
66
+ "SendDSL" : SendDSL,
67
+
68
+ "module" : module,
69
+
70
+ "router": router,
71
+ "adapter_server": adapter_server,
72
+ }
73
+
74
+ for module_name, moduleObj in BaseModules.items():
75
+ setattr(sdk, module_name, moduleObj)
76
+
77
+ logger.debug("ErisPulse 正在挂载loop循环器...")
78
+
79
+ # 设置默认loop循环捕捉器
80
+ asyncio_loop = asyncio.get_event_loop()
81
+ exceptions.setup_async_loop(asyncio_loop)
82
+
83
+ logger.debug("SDK核心模块挂载完毕")
84
+
85
+ class LazyModule:
86
+ """
87
+ 懒加载模块包装器
88
+
89
+ 当模块第一次被访问时才进行实例化
90
+
91
+ {!--< tips >!--}
92
+ 1. 模块的实际实例化会在第一次属性访问时进行
93
+ 2. 依赖模块会在被使用时自动初始化
94
+ 3. 对于继承自 BaseModule 的模块,会自动调用生命周期方法
95
+ {!--< /tips >!--}
96
+ """
97
+
98
+ def __init__(self, module_name: str, module_class: Type, sdk_ref: Any, module_info: Dict[str, Any]) -> None:
99
+ """
100
+ 初始化懒加载包装器
101
+
102
+ :param module_name: str 模块名称
103
+ :param module_class: Type 模块类
104
+ :param sdk_ref: Any SDK引用
105
+ :param module_info: Dict[str, Any] 模块信息字典
106
+ """
107
+ # 使用object.__setattr__避免触发自定义的__setattr__
108
+ object.__setattr__(self, '_module_name', module_name)
109
+ object.__setattr__(self, '_module_class', module_class)
110
+ object.__setattr__(self, '_sdk_ref', sdk_ref)
111
+ object.__setattr__(self, '_module_info', module_info)
112
+ object.__setattr__(self, '_instance', None)
113
+ object.__setattr__(self, '_initialized', False)
114
+ object.__setattr__(self, '_is_base_module', module_info.get("meta", {}).get("is_base_module", False))
115
+
116
+ async def _initialize(self):
117
+ """
118
+ 实际初始化模块
119
+
120
+ :raises LazyLoadError: 当模块初始化失败时抛出
121
+ """
122
+ # 避免重复初始化
123
+ if object.__getattribute__(self, '_initialized'):
124
+ return
125
+
126
+ logger.debug(f"正在初始化懒加载模块 {object.__getattribute__(self, '_module_name')}...")
127
+
128
+ try:
129
+ # 获取类的__init__参数信息
130
+ logger.debug(f"正在获取模块 {object.__getattribute__(self, '_module_name')} 的 __init__ 参数信息...")
131
+ init_signature = inspect.signature(object.__getattribute__(self, '_module_class').__init__)
132
+ params = init_signature.parameters
133
+
134
+ # 根据参数决定是否传入sdk
135
+ if 'sdk' in params:
136
+ logger.debug(f"模块 {object.__getattribute__(self, '_module_name')} 需要传入 sdk 参数")
137
+ instance = object.__getattribute__(self, '_module_class')(object.__getattribute__(self, '_sdk_ref'))
138
+ else:
139
+ logger.debug(f"模块 {object.__getattribute__(self, '_module_name')} 不需要传入 sdk 参数")
140
+ instance = object.__getattribute__(self, '_module_class')()
141
+
142
+ logger.debug(f"正在设置模块 {object.__getattribute__(self, '_module_name')} 的 moduleInfo 属性...")
143
+ setattr(instance, "moduleInfo", object.__getattribute__(self, '_module_info'))
144
+
145
+ # 使用object.__setattr__避免触发自定义的__setattr__
146
+ object.__setattr__(self, '_instance', instance)
147
+ object.__setattr__(self, '_initialized', True)
148
+
149
+ # 如果是 BaseModule 子类,在初始化后调用 on_load 方法
150
+ if object.__getattribute__(self, '_is_base_module'):
151
+ logger.debug(f"正在调用模块 {object.__getattribute__(self, '_module_name')} 的 on_load 方法...")
152
+
153
+ try:
154
+ await module.load(object.__getattribute__(self, '_module_name'))
155
+ except Exception as e:
156
+ logger.error(f"调用模块 {object.__getattribute__(self, '_module_name')} 的 on_load 方法时出错: {e}")
157
+
158
+ await lifecycle.submit_event(
159
+ "module.init",
160
+ msg=f"模块 {object.__getattribute__(self, '_module_name')} 初始化完毕",
161
+ data={
162
+ "module_name": object.__getattribute__(self, '_module_name'),
163
+ "success": True,
164
+ }
165
+ )
166
+ logger.debug(f"懒加载模块 {object.__getattribute__(self, '_module_name')} 初始化完成")
167
+
168
+ except Exception as e:
169
+ await lifecycle.submit_event(
170
+ "module.init",
171
+ msg=f"模块初始化失败: {e}",
172
+ data={
173
+ "module_name": object.__getattribute__(self, '_module_name'),
174
+ "success": False,
175
+ }
176
+ )
177
+ logger.error(f"懒加载模块 {object.__getattribute__(self, '_module_name')} 初始化失败: {e}")
178
+ raise e
179
+
180
+ def _initialize_sync(self):
181
+ """
182
+ 同步初始化模块,用于在异步上下文中进行同步调用
183
+
184
+ :raises LazyLoadError: 当模块初始化失败时抛出
185
+ """
186
+ # 避免重复初始化
187
+ if object.__getattribute__(self, '_initialized'):
188
+ return
189
+
190
+ logger.debug(f"正在同步初始化懒加载模块 {object.__getattribute__(self, '_module_name')}...")
191
+
192
+ try:
193
+ # 获取类的__init__参数信息
194
+ logger.debug(f"正在获取模块 {object.__getattribute__(self, '_module_name')} 的 __init__ 参数信息...")
195
+ init_signature = inspect.signature(object.__getattribute__(self, '_module_class').__init__)
196
+ params = init_signature.parameters
197
+
198
+ # 根据参数决定是否传入sdk
199
+ if 'sdk' in params:
200
+ logger.debug(f"模块 {object.__getattribute__(self, '_module_name')} 需要传入 sdk 参数")
201
+ instance = object.__getattribute__(self, '_module_class')(object.__getattribute__(self, '_sdk_ref'))
202
+ else:
203
+ logger.debug(f"模块 {object.__getattribute__(self, '_module_name')} 不需要传入 sdk 参数")
204
+ instance = object.__getattribute__(self, '_module_class')()
205
+
206
+ logger.debug(f"正在设置模块 {object.__getattribute__(self, '_module_name')} 的 moduleInfo 属性...")
207
+ setattr(instance, "moduleInfo", object.__getattribute__(self, '_module_info'))
208
+
209
+ # 使用object.__setattr__避免触发自定义的__setattr__
210
+ object.__setattr__(self, '_instance', instance)
211
+ object.__setattr__(self, '_initialized', True)
212
+ object.__setattr__(self, '_needs_async_init', False) # 确保清除异步初始化标志
213
+
214
+ # 注意:在同步初始化中,我们不能调用异步的 module.load 和 lifecycle.submit_event
215
+ # 这些将在异步上下文中延迟处理
216
+
217
+ logger.debug(f"懒加载模块 {object.__getattribute__(self, '_module_name')} 同步初始化完成")
218
+
219
+ except Exception as e:
220
+ logger.error(f"懒加载模块 {object.__getattribute__(self, '_module_name')} 同步初始化失败: {e}")
221
+ raise e
222
+
223
+ async def _complete_async_init(self):
224
+ """
225
+ 完成异步初始化部分,用于同步初始化后的异步处理
226
+
227
+ 这个方法用于处理 module.load 和事件提交等异步操作
228
+ """
229
+ if not object.__getattribute__(self, '_initialized'):
230
+ return
231
+
232
+ try:
233
+ # 如果是 BaseModule 子类,在初始化后调用 on_load 方法
234
+ if object.__getattribute__(self, '_is_base_module'):
235
+ logger.debug(f"正在异步调用模块 {object.__getattribute__(self, '_module_name')} 的 on_load 方法...")
236
+
237
+ try:
238
+ await module.load(object.__getattribute__(self, '_module_name'))
239
+ except Exception as e:
240
+ logger.error(f"异步调用模块 {object.__getattribute__(self, '_module_name')} 的 on_load 方法时出错: {e}")
241
+
242
+ await lifecycle.submit_event(
243
+ "module.init",
244
+ msg=f"模块 {object.__getattribute__(self, '_module_name')} 初始化完毕",
245
+ data={
246
+ "module_name": object.__getattribute__(self, '_module_name'),
247
+ "success": True,
248
+ }
249
+ )
250
+ logger.debug(f"懒加载模块 {object.__getattribute__(self, '_module_name')} 异步初始化部分完成")
251
+ except Exception as e:
252
+ await lifecycle.submit_event(
253
+ "module.init",
254
+ msg=f"模块初始化失败: {e}",
255
+ data={
256
+ "module_name": object.__getattribute__(self, '_module_name'),
257
+ "success": False,
258
+ }
259
+ )
260
+ logger.error(f"懒加载模块 {object.__getattribute__(self, '_module_name')} 异步初始化部分失败: {e}")
261
+
262
+ def _ensure_initialized(self) -> None:
263
+ """
264
+ 确保模块已初始化
265
+
266
+ :raises LazyLoadError: 当模块未初始化时抛出
267
+ """
268
+ if not object.__getattribute__(self, '_initialized'):
269
+ # 检查当前是否在异步上下文中
270
+ try:
271
+ loop = asyncio.get_running_loop()
272
+ # 如果在异步上下文中,我们需要检查模块初始化方法是否需要异步
273
+ init_method = getattr(object.__getattribute__(self, '_module_class'), '__init__', None)
274
+
275
+ # 检查__init__方法是否是协程函数
276
+ if asyncio.iscoroutinefunction(init_method):
277
+ # 对于需要异步初始化的模块,我们只能设置一个标志,提示需要异步初始化
278
+ object.__setattr__(self, '_needs_async_init', True)
279
+ logger.warning(f"模块 {object.__getattribute__(self, '_module_name')} 需要异步初始化,请在异步上下文中调用")
280
+ return
281
+ else:
282
+ # 对于同步初始化的模块,使用同步初始化方式
283
+ self._initialize_sync()
284
+
285
+ # 异步处理需要在初始化后完成的事件
286
+ if object.__getattribute__(self, '_is_base_module'):
287
+ # 调度异步任务来处理 module.load 和事件提交
288
+ try:
289
+ loop = asyncio.get_running_loop()
290
+ loop.create_task(self._complete_async_init())
291
+ except Exception as e:
292
+ logger.warning(f"无法调度异步初始化任务: {e}")
293
+ except RuntimeError:
294
+ # 没有运行中的事件循环,可以安全地创建新的事件循环
295
+ asyncio.run(self._initialize())
296
+
297
+ def __getattr__(self, name: str) -> Any:
298
+ """
299
+ 属性访问时触发初始化
300
+
301
+ :param name: str 属性名
302
+ :return: Any 属性值
303
+ """
304
+ logger.debug(f"正在访问懒加载模块 {object.__getattribute__(self, '_module_name')} 的属性 {name}...")
305
+
306
+ # 检查是否需要异步初始化
307
+ if hasattr(self, '_needs_async_init') and object.__getattribute__(self, '_needs_async_init'):
308
+ raise RuntimeError(
309
+ f"模块 {object.__getattribute__(self, '_module_name')} 需要异步初始化,"
310
+ f"请使用 'await sdk.load_module(\"{object.__getattribute__(self, '_module_name')}\")' 来初始化模块"
311
+ )
312
+
313
+ self._ensure_initialized()
314
+ return getattr(object.__getattribute__(self, '_instance'), name)
315
+
316
+ def __setattr__(self, name: str, value: Any) -> None:
317
+ """
318
+ 属性设置
319
+
320
+ :param name: str 属性名
321
+ :param value: Any 属性值
322
+ """
323
+ logger.debug(f"正在设置懒加载模块 {object.__getattribute__(self, '_module_name')} 的属性 {name}...")
324
+
325
+ # 特殊属性直接设置到包装器上
326
+ if name.startswith('_') or name in ('moduleInfo',):
327
+ object.__setattr__(self, name, value)
328
+ else:
329
+ # 其他属性在初始化前设置到包装器上,初始化后设置到实际模块实例上
330
+ if name == '_instance' or not hasattr(self, '_initialized') or not object.__getattribute__(self, '_initialized'):
331
+ object.__setattr__(self, name, value)
332
+ else:
333
+ setattr(object.__getattribute__(self, '_instance'), name, value)
334
+
335
+ def __delattr__(self, name: str) -> None:
336
+ """
337
+ 属性删除
338
+
339
+ :param name: str 属性名
340
+ """
341
+ logger.debug(f"正在删除懒加载模块 {object.__getattribute__(self, '_module_name')} 的属性 {name}...")
342
+
343
+ self._ensure_initialized()
344
+ delattr(object.__getattribute__(self, '_instance'), name)
345
+
346
+ def __getattribute__(self, name: str) -> Any:
347
+ """
348
+ 属性访问,初始化后直接委托给实际实例
349
+
350
+ :param name: str 属性名
351
+ :return: Any 属性值
352
+ """
353
+ # 特殊属性直接从包装器获取
354
+ if name.startswith('_') or name in ('moduleInfo',):
355
+ return object.__getattribute__(self, name)
356
+
357
+ # 检查是否已初始化
358
+ try:
359
+ initialized = object.__getattribute__(self, '_initialized')
360
+ except AttributeError:
361
+ # 避免在初始化过程中访问_initialized时出现递归
362
+ return object.__getattribute__(self, name)
363
+
364
+ if not initialized:
365
+ # 确保初始化
366
+ self._ensure_initialized()
367
+ # 重新获取initialized状态
368
+ initialized = object.__getattribute__(self, '_initialized')
369
+
370
+ # 初始化后直接委托给实际实例
371
+ if initialized:
372
+ instance = object.__getattribute__(self, '_instance')
373
+ return getattr(instance, name)
374
+ else:
375
+ return object.__getattribute__(self, name)
376
+
377
+ def __dir__(self) -> List[str]:
378
+ """
379
+ 返回模块属性列表
380
+
381
+ :return: List[str] 属性列表
382
+ """
383
+ logger.debug(f"正在获取懒加载模块 {object.__getattribute__(self, '_module_name')} 的属性列表...")
384
+
385
+ self._ensure_initialized()
386
+ return dir(object.__getattribute__(self, '_instance'))
387
+
388
+ def __repr__(self) -> str:
389
+ """
390
+ 返回模块表示字符串
391
+
392
+ :return: str 表示字符串
393
+ """
394
+ logger.debug(f"正在获取懒加载模块 {object.__getattribute__(self, '_module_name')} 的表示字符串...")
395
+
396
+ if object.__getattribute__(self, '_initialized'):
397
+ return repr(object.__getattribute__(self, '_instance'))
398
+ return f"<LazyModule {object.__getattribute__(self, '_module_name')} (not initialized)>"
399
+
400
+ # 代理所有其他魔术方法到实际模块实例
401
+ def __call__(self, *args, **kwargs):
402
+ """代理函数调用"""
403
+ self._ensure_initialized()
404
+ return object.__getattribute__(self, '_instance')(*args, **kwargs)
405
+
406
+
407
+ class AdapterLoader:
408
+ """
409
+ 适配器加载器
410
+
411
+ 专门用于从PyPI包加载和初始化适配器
412
+
413
+ {!--< tips >!--}
414
+ 1. 适配器必须通过entry-points机制注册到erispulse.adapter组
415
+ 2. 适配器类必须继承BaseAdapter
416
+ 3. 适配器不适用懒加载
417
+ {!--< /tips >!--}
418
+ """
419
+
420
+ @staticmethod
421
+ async def load() -> Tuple[Dict[str, object], List[str], List[str]]:
422
+ """
423
+ 从PyPI包entry-points加载适配器
424
+
425
+ :return:
426
+ Dict[str, object]: 适配器对象字典 {适配器名: 模块对象}
427
+ List[str]: 启用的适配器名称列表
428
+ List[str]: 停用的适配器名称列表
429
+
430
+ :raises ImportError: 当无法加载适配器时抛出
431
+ """
432
+ adapter_objs = {}
433
+ enabled_adapters = []
434
+ disabled_adapters = []
435
+
436
+ logger.info("正在加载适配器entry-points...")
437
+
438
+ try:
439
+ # 加载适配器entry-points
440
+ logger.debug("正在获取适配器entry-points...")
441
+ entry_points = importlib.metadata.entry_points()
442
+ if hasattr(entry_points, 'select'):
443
+ adapter_entries = entry_points.select(group='erispulse.adapter')
444
+ else:
445
+ adapter_entries = entry_points.get('erispulse.adapter', []) # type: ignore[attr-defined] || 原因: 3.10.0后entry_points不再支持select方法
446
+
447
+ # 处理适配器
448
+ logger.debug("正在处理适配器entry-points...")
449
+ for entry_point in adapter_entries:
450
+ adapter_objs, enabled_adapters, disabled_adapters = await AdapterLoader._process_adapter(
451
+ entry_point, adapter_objs, enabled_adapters, disabled_adapters)
452
+
453
+ logger.info("适配器加载完成")
454
+
455
+ except Exception as e:
456
+ logger.error(f"加载适配器entry-points失败: {e}")
457
+ raise ImportError(f"无法加载适配器: {e}")
458
+
459
+ return adapter_objs, enabled_adapters, disabled_adapters
460
+
461
+ @staticmethod
462
+ async def _process_adapter(
463
+ entry_point: Any,
464
+ adapter_objs: Dict[str, object],
465
+ enabled_adapters: List[str],
466
+ disabled_adapters: List[str]
467
+ ) -> Tuple[Dict[str, object], List[str], List[str]]:
468
+ """
469
+ {!--< internal-use >!--}
470
+ 处理单个适配器entry-point
471
+
472
+ :param entry_point: entry-point对象
473
+ :param adapter_objs: 适配器对象字典
474
+ :param enabled_adapters: 启用的适配器列表
475
+ :param disabled_adapters: 停用的适配器列表
476
+
477
+ :return:
478
+ Dict[str, object]: 更新后的适配器对象字典
479
+ List[str]: 更新后的启用适配器列表
480
+ List[str]: 更新后的禁用适配器列表
481
+
482
+ :raises ImportError: 当适配器加载失败时抛出
483
+ """
484
+ meta_name = entry_point.name
485
+
486
+ # # 检查适配器是否已经注册,如果未注册则进行注册(默认禁用)
487
+ # if not sdk.adapter.exists(meta_name):
488
+ # sdk.adapter._config_register(meta_name, False)
489
+ # logger.info(f"发现新适配器 {meta_name},默认已禁用,请在配置文件中配置适配器并决定是否启用")
490
+ if not sdk.adapter.exists(meta_name):
491
+ sdk.adapter._config_register(meta_name, True)
492
+ logger.info(f"发现新适配器 {meta_name},默认已启用")
493
+
494
+ # 获取适配器当前状态
495
+ adapter_status = sdk.adapter.is_enabled(meta_name)
496
+ logger.debug(f"适配器 {meta_name} 状态: {adapter_status}")
497
+
498
+ if not adapter_status:
499
+ disabled_adapters.append(meta_name)
500
+ logger.debug(f"适配器 {meta_name} 已禁用, 跳过...")
501
+ return adapter_objs, enabled_adapters, disabled_adapters
502
+
503
+ try:
504
+ loaded_class = entry_point.load()
505
+ adapter_obj = sys.modules[loaded_class.__module__]
506
+ dist = importlib.metadata.distribution(entry_point.dist.name)
507
+
508
+ adapter_info = {
509
+ "meta": {
510
+ "name": meta_name,
511
+ "version": getattr(adapter_obj, "__version__", dist.version if dist else "1.0.0"),
512
+ "description": getattr(adapter_obj, "__description__", ""),
513
+ "author": getattr(adapter_obj, "__author__", ""),
514
+ "license": getattr(adapter_obj, "__license__", ""),
515
+ "package": entry_point.dist.name
516
+ },
517
+ "adapter_class": loaded_class
518
+ }
519
+
520
+ if not hasattr(adapter_obj, 'adapterInfo'):
521
+ setattr(adapter_obj, 'adapterInfo', {})
522
+
523
+ adapter_obj.adapterInfo[meta_name] = adapter_info
524
+
525
+ adapter_objs[meta_name] = adapter_obj
526
+ enabled_adapters.append(meta_name)
527
+ logger.debug(f"从PyPI包发现适配器: {meta_name}")
528
+
529
+ except Exception as e:
530
+ logger.warning(f"从entry-point加载适配器 {meta_name} 失败: {e}")
531
+ raise ImportError(f"无法加载适配器 {meta_name}: {e}")
532
+
533
+ return adapter_objs, enabled_adapters, disabled_adapters
534
+
535
+ class ModuleLoader:
536
+ """
537
+ 模块加载器
538
+
539
+ 专门用于从PyPI包加载和初始化普通模块
540
+
541
+ {!--< tips >!--}
542
+ 1. 模块必须通过entry-points机制注册到erispulse.module组
543
+ 2. 模块类名应与entry-point名称一致
544
+ {!--< /tips >!--}
545
+ """
546
+
547
+ @staticmethod
548
+ async def load() -> Tuple[Dict[str, object], List[str], List[str]]:
549
+ """
550
+ 从PyPI包entry-points加载模块
551
+
552
+ :return:
553
+ Dict[str, object]: 模块对象字典 {模块名: 模块对象}
554
+ List[str]: 启用的模块名称列表
555
+ List[str]: 停用的模块名称列表
556
+
557
+ :raises ImportError: 当无法加载模块时抛出
558
+ """
559
+ module_objs = {}
560
+ enabled_modules = []
561
+ disabled_modules = []
562
+
563
+ logger.info("正在加载模块entry-points...")
564
+
565
+ try:
566
+ # 加载模块entry-points
567
+ entry_points = importlib.metadata.entry_points()
568
+ if hasattr(entry_points, 'select'):
569
+ module_entries = entry_points.select(group='erispulse.module')
570
+ else:
571
+ module_entries = entry_points.get('erispulse.module', []) # type: ignore[attr-defined] || 原因: 3.10.0后entry_points不再支持select方法
572
+
573
+ # 处理模块
574
+ for entry_point in module_entries:
575
+ module_objs, enabled_modules, disabled_modules = await ModuleLoader._process_module(
576
+ entry_point, module_objs, enabled_modules, disabled_modules)
577
+
578
+ logger.info("模块加载完成")
579
+
580
+ except Exception as e:
581
+ logger.error(f"加载模块entry-points失败: {e}")
582
+ raise ImportError(f"无法加载模块: {e}")
583
+
584
+ return module_objs, enabled_modules, disabled_modules
585
+
586
+ @staticmethod
587
+ async def _process_module(
588
+ entry_point: Any,
589
+ module_objs: Dict[str, object],
590
+ enabled_modules: List[str],
591
+ disabled_modules: List[str]
592
+ ) -> Tuple[Dict[str, object], List[str], List[str]]:
593
+ """
594
+ {!--< internal-use >!--}
595
+ 处理单个模块entry-point
596
+
597
+ :param entry_point: entry-point对象
598
+ :param module_objs: 模块对象字典
599
+ :param enabled_modules: 启用的模块列表
600
+ :param disabled_modules: 停用的模块列表
601
+
602
+ :return:
603
+ Dict[str, object]: 更新后的模块对象字典
604
+ List[str]: 更新后的启用模块列表
605
+ List[str]: 更新后的禁用模块列表
606
+
607
+ :raises ImportError: 当模块加载失败时抛出
608
+ """
609
+ meta_name = entry_point.name
610
+
611
+ logger.debug(f"正在处理模块: {meta_name}")
612
+ # # 检查模块是否已经注册,如果未注册则进行注册(默认禁用)
613
+ # if not sdk.module.exists(meta_name):
614
+ # sdk.module._config_register(meta_name, False) # 默认禁用
615
+ # logger.info(f"发现新模块 {meta_name},默认已禁用,请在配置文件中手动启用")
616
+
617
+ if not sdk.module.exists(meta_name):
618
+ sdk.module._config_register(meta_name, True) # 默认启用
619
+ logger.info(f"发现新模块 {meta_name},默认已启用。如需禁用,请在配置文件中设置 ErisPulse.modules.status.{meta_name} = false")
620
+
621
+ # 获取模块当前状态
622
+ module_status = sdk.module.is_enabled(meta_name)
623
+ logger.debug(f"模块 {meta_name} 状态: {module_status}")
624
+
625
+ if not module_status:
626
+ disabled_modules.append(meta_name)
627
+ return module_objs, enabled_modules, disabled_modules
628
+
629
+ try:
630
+ loaded_obj = entry_point.load()
631
+ module_obj = sys.modules[loaded_obj.__module__]
632
+ dist = importlib.metadata.distribution(entry_point.dist.name)
633
+
634
+ # 检查模块是否继承自 BaseModule
635
+ from .Core.Bases.module import BaseModule
636
+ is_base_module = inspect.isclass(loaded_obj) and issubclass(loaded_obj, BaseModule)
637
+
638
+ if not is_base_module:
639
+ logger.warning(f"模块 {meta_name} 未继承自 BaseModule,"\
640
+ "如果你是这个模块的作者,请检查 ErisPulse 的文档更新 并尽快迁移!")
641
+
642
+ lazy_load = ModuleLoader._should_lazy_load(loaded_obj)
643
+
644
+ module_info = {
645
+ "meta": {
646
+ "name": meta_name,
647
+ "version": getattr(module_obj, "__version__", dist.version if dist else "1.0.0"),
648
+ "description": getattr(module_obj, "__description__", ""),
649
+ "author": getattr(module_obj, "__author__", ""),
650
+ "license": getattr(module_obj, "__license__", ""),
651
+ "package": entry_point.dist.name,
652
+ "lazy_load": lazy_load,
653
+ "is_base_module": is_base_module
654
+ },
655
+ "module_class": loaded_obj
656
+ }
657
+
658
+ setattr(module_obj, "moduleInfo", module_info)
659
+
660
+ module_objs[meta_name] = module_obj
661
+ enabled_modules.append(meta_name)
662
+ logger.debug(f"从PyPI包加载模块: {meta_name}")
663
+
664
+ except Exception as e:
665
+ logger.warning(f"从entry-point加载模块 {meta_name} 失败: {e}")
666
+ raise ImportError(f"无法加载模块 {meta_name}: {e}")
667
+
668
+ return module_objs, enabled_modules, disabled_modules
669
+
670
+ @staticmethod
671
+ def _should_lazy_load(module_class: Type) -> bool:
672
+ """
673
+ 检查模块是否应该懒加载
674
+
675
+ :param module_class: Type 模块类
676
+ :return: bool 如果返回 False,则立即加载;否则懒加载
677
+ """
678
+
679
+ logger.debug(f"检查模块 {module_class.__name__} 是否应该懒加载")
680
+
681
+ # 首先检查全局懒加载配置
682
+ try:
683
+ from .Core._self_config import get_framework_config
684
+ framework_config = get_framework_config()
685
+ global_lazy_loading = framework_config.get("enable_lazy_loading", True)
686
+
687
+ # 如果全局禁用懒加载,则直接返回False
688
+ if not global_lazy_loading:
689
+ logger.debug(f"全局懒加载已禁用,模块 {module_class.__name__} 将立即加载")
690
+ return False
691
+ except Exception as e:
692
+ logger.warning(f"获取框架配置失败: {e},将使用模块默认配置")
693
+
694
+ # 检查模块是否定义了 should_eager_load() 方法
695
+ if hasattr(module_class, "should_eager_load"):
696
+ try:
697
+ # 调用静态方法,如果返回 True,则禁用懒加载(立即加载)
698
+ return not module_class.should_eager_load()
699
+ except Exception as e:
700
+ logger.warning(f"调用模块 {module_class.__name__} 的 should_eager_load() 失败: {e}")
701
+
702
+ # 默认启用懒加载
703
+ return True
704
+
705
+ class ModuleInitializer:
706
+ """
707
+ 模块初始化器(注意:适配器是一个特殊的模块)
708
+
709
+ 负责协调适配器和模块的初始化流程
710
+
711
+ {!--< tips >!--}
712
+ 1. 初始化顺序:适配器 → 模块
713
+ 2. 模块初始化采用懒加载机制
714
+ {!--< /tips >!--}
715
+ """
716
+
717
+ @staticmethod
718
+ async def init() -> bool:
719
+ """
720
+ 初始化所有模块和适配器
721
+
722
+ 执行步骤:
723
+ 1. 从PyPI包加载适配器
724
+ 2. 从PyPI包加载模块
725
+ 3. 预记录所有模块信息
726
+ 4. 注册适配器
727
+ 5. 初始化各模块
728
+
729
+ :return: bool 初始化是否成功
730
+ :raises InitError: 当初始化失败时抛出
731
+ """
732
+ logger.info("[Init] SDK 正在初始化...")
733
+
734
+ try:
735
+ # 1. 并行加载适配器和模块
736
+ (adapter_result, module_result) = await asyncio.gather(
737
+ AdapterLoader.load(),
738
+ ModuleLoader.load(),
739
+ return_exceptions=True
740
+ )
741
+
742
+ # 检查是否有异常
743
+ if isinstance(adapter_result, Exception):
744
+ logger.error(f"[Init] 适配器加载失败: {adapter_result}")
745
+ return False
746
+
747
+ if isinstance(module_result, Exception):
748
+ logger.error(f"[Init] 模块加载失败: {module_result}")
749
+ return False
750
+
751
+ # 解包结果
752
+ if not isinstance(adapter_result, Exception):
753
+ adapter_objs, enabled_adapters, disabled_adapters = adapter_result # type: ignore[assignment] || 原因: 已经在方法中进行了类型检查
754
+ else:
755
+ return False
756
+
757
+ if not isinstance(module_result, Exception):
758
+ module_objs, enabled_modules, disabled_modules = module_result # type: ignore[assignment] || 原因: 已经在方法中进行了类型检查
759
+ else:
760
+ return False
761
+
762
+ logger.info(f"[Init] 加载了 {len(enabled_adapters)} 个适配器, {len(disabled_adapters)} 个适配器被禁用")
763
+ logger.info(f"[Init] 加载了 {len(enabled_modules)} 个模块, {len(disabled_modules)} 个模块被禁用")
764
+
765
+ modules_dir = os.path.join(os.path.dirname(__file__), "modules")
766
+ if os.path.exists(modules_dir) and os.listdir(modules_dir):
767
+ logger.warning("[Warning] 你的项目使用了已经弃用的模块加载方式, 请尽快使用 PyPI 模块加载方式代替")
768
+
769
+ if not enabled_modules and not enabled_adapters:
770
+ logger.warning("[Init] 没有找到可用的模块和适配器")
771
+ return True
772
+
773
+ # 3. 注册适配器
774
+ logger.debug("[Init] 正在注册适配器...")
775
+ if not await ModuleInitializer._register_adapters(enabled_adapters, adapter_objs):
776
+ return False
777
+
778
+ # 4. 初始化模块
779
+ logger.debug("[Init] 正在初始化模块...")
780
+ success = await ModuleInitializer._initialize_modules(enabled_modules, module_objs)
781
+
782
+ if success:
783
+ logger.info("[Init] SDK初始化成功")
784
+ else:
785
+ logger.error("[Init] SDK初始化失败")
786
+
787
+ load_duration = lifecycle.stop_timer("core.init")
788
+ await lifecycle.submit_event(
789
+ "core.init.complete",
790
+ msg="模块初始化完成" if success else "模块初始化失败",
791
+ data={
792
+ "duration": load_duration,
793
+ "success": success
794
+ }
795
+ )
796
+ return success
797
+
798
+ except Exception as e:
799
+ load_duration = lifecycle.stop_timer("core.init")
800
+ await lifecycle.submit_event(
801
+ "core.init.complete",
802
+ msg="模块初始化失败",
803
+ data={
804
+ "duration": load_duration,
805
+ "success": False
806
+ }
807
+ )
808
+ logger.critical(f"SDK初始化严重错误: {e}")
809
+ return False
810
+ @staticmethod
811
+ async def _initialize_modules(modules: List[str], module_objs: Dict[str, Any]) -> bool:
812
+ """
813
+ {!--< internal-use >!--}
814
+ 初始化模块
815
+
816
+ :param modules: List[str] 模块名称列表
817
+ :param module_objs: Dict[str, Any] 模块对象字典
818
+
819
+ :return: bool 模块初始化是否成功
820
+ """
821
+ # 并行注册所有模块类
822
+ register_tasks = []
823
+ for module_name in modules:
824
+ module_obj = module_objs[module_name]
825
+ meta_name = module_obj.moduleInfo["meta"]["name"]
826
+
827
+ async def register_module(name, obj):
828
+ try:
829
+ entry_points = importlib.metadata.entry_points()
830
+ if hasattr(entry_points, 'select'):
831
+ module_entries = entry_points.select(group='erispulse.module')
832
+ module_entry_map = {entry.name: entry for entry in module_entries}
833
+ else:
834
+ module_entries = entry_points.get('erispulse.module', []) # type: ignore[assignment] || 原因: 已经在方法中进行了类型检查,这是一个兼容性的写法
835
+ module_entry_map = {entry.name: entry for entry in module_entries}
836
+
837
+ entry_point = module_entry_map.get(name)
838
+ if entry_point:
839
+ module_class = entry_point.load()
840
+
841
+ module.register(name, module_class, obj.moduleInfo)
842
+ logger.debug(f"注册模块类: {name}")
843
+ return True
844
+ return False
845
+ except Exception as e:
846
+ logger.error(f"注册模块 {name} 失败: {e}")
847
+ return False
848
+
849
+ register_tasks.append(register_module(meta_name, module_obj))
850
+
851
+ # 等待所有注册任务完成
852
+ register_results = await asyncio.gather(*register_tasks, return_exceptions=True)
853
+
854
+ # 检查是否有注册失败的情况
855
+ if any(isinstance(result, Exception) or result is False for result in register_results):
856
+ return False
857
+
858
+ # 将所有模块挂载到sdk对象上
859
+ for module_name in modules:
860
+ module_obj = module_objs[module_name]
861
+ meta_name = module_obj.moduleInfo["meta"]["name"]
862
+ lazy_load = module_obj.moduleInfo["meta"].get("lazy_load", True)
863
+
864
+ if lazy_load:
865
+ # 使用懒加载方式挂载
866
+ lazy_module = LazyModule(
867
+ meta_name,
868
+ module_obj.moduleInfo["module_class"],
869
+ sdk,
870
+ module_obj.moduleInfo
871
+ )
872
+ setattr(sdk, meta_name, lazy_module)
873
+ logger.debug(f"挂载懒加载模块到sdk: {meta_name}")
874
+ else:
875
+ # 立即加载的模块暂时挂载为None,稍后会加载
876
+ setattr(sdk, meta_name, None)
877
+ logger.debug(f"预挂载立即加载模块到sdk: {meta_name}")
878
+
879
+ # 并行初始化需要立即加载的模块
880
+ eager_load_tasks = []
881
+ for module_name in modules:
882
+ module_obj = module_objs[module_name]
883
+ meta_name = module_obj.moduleInfo["meta"]["name"]
884
+
885
+ async def load_module_if_eager(name, obj):
886
+ try:
887
+ # 检查是否需要立即加载
888
+ entry_points = importlib.metadata.entry_points()
889
+ if hasattr(entry_points, 'select'):
890
+ module_entries = entry_points.select(group='erispulse.module')
891
+ module_entry_map = {entry.name: entry for entry in module_entries}
892
+ else:
893
+ module_entries = entry_points.get('erispulse.module', []) # type: ignore[assignment] || 原因: 已经在方法中进行了类型检查,这是一个兼容性的写法
894
+ module_entry_map = {entry.name: entry for entry in module_entries}
895
+
896
+ entry_point = module_entry_map.get(name)
897
+ if entry_point:
898
+ module_class = entry_point.load()
899
+
900
+ # 检查是否需要立即加载
901
+ lazy_load = ModuleLoader._should_lazy_load(module_class)
902
+ if not lazy_load:
903
+ # 立即加载模块
904
+ result = await module.load(name)
905
+ if not result:
906
+ logger.error(f"加载模块 {name} 失败")
907
+ else:
908
+ logger.debug(f"立即加载模块: {name}")
909
+ # 更新sdk上的引用
910
+ setattr(sdk, name, module.get(name))
911
+ return result
912
+ return True # 不需要立即加载的模块返回True
913
+ except Exception as e:
914
+ logger.error(f"初始化模块 {name} 失败: {e}")
915
+ return False
916
+
917
+ eager_load_tasks.append(load_module_if_eager(meta_name, module_obj))
918
+
919
+ # 等待所有立即加载任务完成
920
+ load_results = await asyncio.gather(*eager_load_tasks, return_exceptions=True)
921
+
922
+ # 检查是否有加载失败的情况
923
+ return not any(isinstance(result, Exception) or result is False for result in load_results)
924
+
925
+ @staticmethod
926
+ async def _register_adapters(adapters: List[str], adapter_objs: Dict[str, Any]) -> bool:
927
+ """
928
+ {!--< internal-use >!--}
929
+ 注册适配器
930
+
931
+ :param adapters: List[str] 适配器名称列表
932
+ :param adapter_objs: Dict[str, Any] 适配器对象字典
933
+
934
+ :return: bool 适配器注册是否成功
935
+ """
936
+ # 并行注册所有适配器
937
+ register_tasks = []
938
+
939
+ for adapter_name in adapters:
940
+ adapter_obj = adapter_objs[adapter_name]
941
+
942
+ async def register_single_adapter(name, obj):
943
+ try:
944
+ success = True
945
+ if hasattr(obj, "adapterInfo") and isinstance(obj.adapterInfo, dict):
946
+ for platform, adapter_info in obj.adapterInfo.items():
947
+ if platform in adapter._adapters:
948
+ continue
949
+
950
+ adapter_class = adapter_info["adapter_class"]
951
+
952
+ adapter.register(platform, adapter_class, adapter_info)
953
+ logger.info(f"注册适配器: {platform} ({adapter_class.__name__})")
954
+
955
+ # 提交适配器加载完成事件
956
+ await lifecycle.submit_event(
957
+ "adapter.load",
958
+ msg=f"适配器 {platform} 加载完成",
959
+ data={
960
+ "platform": platform,
961
+ "success": True
962
+ }
963
+ )
964
+ return success
965
+ except Exception as e:
966
+ logger.error(f"适配器 {name} 注册失败: {e}")
967
+ # 提交适配器加载失败事件
968
+ await lifecycle.submit_event(
969
+ "adapter.load",
970
+ msg=f"适配器 {name} 加载失败: {e}",
971
+ data={
972
+ "platform": name,
973
+ "success": False
974
+ }
975
+ )
976
+ return False
977
+
978
+ register_tasks.append(register_single_adapter(adapter_name, adapter_obj))
979
+
980
+ # 等待所有注册任务完成
981
+ register_results = await asyncio.gather(*register_tasks, return_exceptions=True)
982
+
983
+ # 检查是否有注册失败的情况
984
+ return not any(isinstance(result, Exception) or result is False for result in register_results)
985
+
986
+ async def init_progress() -> bool:
987
+ """
988
+ 初始化项目环境文件
989
+
990
+ 1. 检查并创建main.py入口文件
991
+ 2. 确保基础目录结构存在
992
+
993
+ :return: bool 是否创建了新的main.py文件
994
+
995
+ {!--< tips >!--}
996
+ 1. 如果main.py已存在则不会覆盖
997
+ 2. 此方法通常由SDK内部调用
998
+ {!--< /tips >!--}
999
+ """
1000
+ main_file = Path("main.py")
1001
+ main_init = False
1002
+
1003
+ try:
1004
+ if not main_file.exists():
1005
+ main_content = '''# main.py
1006
+ # ErisPulse 主程序文件
1007
+ # 本文件由 SDK 自动创建,您可随意修改
1008
+ import asyncio
1009
+ from ErisPulse import sdk
1010
+
1011
+ async def main():
1012
+ try:
1013
+ isInit = await sdk.init()
1014
+
1015
+ if not isInit:
1016
+ sdk.logger.error("ErisPulse 初始化失败,请检查日志")
1017
+ return
1018
+
1019
+ await sdk.adapter.startup()
1020
+
1021
+ # 保持程序运行(不建议修改)
1022
+ await asyncio.Event().wait()
1023
+ except Exception as e:
1024
+ sdk.logger.error(e)
1025
+ except KeyboardInterrupt:
1026
+ sdk.logger.info("正在停止程序")
1027
+ finally:
1028
+ await sdk.adapter.shutdown()
1029
+
1030
+ if __name__ == "__main__":
1031
+ asyncio.run(main())
1032
+ '''
1033
+ with open(main_file, "w", encoding="utf-8") as f:
1034
+ f.write(main_content)
1035
+ main_init = True
1036
+
1037
+ return main_init
1038
+ except Exception as e:
1039
+ logger.error(f"无法初始化项目环境: {e}")
1040
+ return False
1041
+
1042
+ async def _prepare_environment() -> bool:
1043
+ """
1044
+ {!--< internal-use >!--}
1045
+ 准备运行环境
1046
+
1047
+ 初始化项目环境文件
1048
+
1049
+ :return: bool 环境准备是否成功
1050
+ """
1051
+ await lifecycle.submit_event(
1052
+ "core.init.start",
1053
+ msg="开始初始化"
1054
+ )
1055
+ lifecycle.start_timer("core.init")
1056
+
1057
+ logger.info("[Init] 准备初始化环境...")
1058
+ try:
1059
+ from .Core._self_config import get_erispulse_config
1060
+ get_erispulse_config()
1061
+ logger.info("[Init] 配置文件已加载")
1062
+
1063
+ main_init = await init_progress()
1064
+ if main_init:
1065
+ logger.info("[Init] 项目入口已生成, 你可以在 main.py 中编写一些代码")
1066
+ return True
1067
+ except Exception as e:
1068
+ load_duration = lifecycle.stop_timer("core.init")
1069
+ await lifecycle.submit_event(
1070
+ "core.init.complete",
1071
+ msg="模块初始化失败",
1072
+ data={
1073
+ "duration": load_duration,
1074
+ "success": False
1075
+ }
1076
+ )
1077
+ logger.error(f"环境准备失败: {e}")
1078
+ return False
1079
+
1080
+ async def init() -> bool:
1081
+ """
1082
+ SDK初始化入口
1083
+
1084
+ :return: bool SDK初始化是否成功
1085
+ """
1086
+ if not await _prepare_environment():
1087
+ return False
1088
+
1089
+ return await ModuleInitializer.init()
1090
+
1091
+ def init_sync() -> bool:
1092
+ """
1093
+ SDK初始化入口(同步版本)
1094
+
1095
+ 用于命令行直接调用,自动在事件循环中运行异步初始化
1096
+
1097
+ :return: bool SDK初始化是否成功
1098
+ """
1099
+ return asyncio.run(init())
1100
+
1101
+ def init_task() -> asyncio.Task:
1102
+ """
1103
+ SDK初始化入口,返回Task对象
1104
+
1105
+ :return: asyncio.Task 初始化任务
1106
+ """
1107
+ async def _async_init():
1108
+ if not await _prepare_environment():
1109
+ return False
1110
+ return await ModuleInitializer.init()
1111
+
1112
+ try:
1113
+ return asyncio.create_task(_async_init())
1114
+ except RuntimeError:
1115
+ loop = asyncio.new_event_loop()
1116
+ asyncio.set_event_loop(loop)
1117
+ return loop.create_task(_async_init())
1118
+
1119
+ async def uninit() -> bool:
1120
+ """
1121
+ SDK反初始化
1122
+
1123
+ 执行以下操作:
1124
+ 1. 关闭所有适配器
1125
+ 2. 卸载所有模块
1126
+ 3. 清理所有事件处理器
1127
+ 4. 清理僵尸线程
1128
+
1129
+ :return: bool 反初始化是否成功
1130
+ """
1131
+ try:
1132
+ logger.info("[Uninit] 开始反初始化SDK...")
1133
+
1134
+ # 1. 关闭所有适配器
1135
+ logger.debug("[Uninit] 正在关闭适配器...")
1136
+ await adapter.shutdown()
1137
+
1138
+ # 2. 卸载所有模块
1139
+ logger.debug("[Uninit] 正在卸载模块...")
1140
+ await module.unload()
1141
+
1142
+ # 3. 清理Event模块中的所有事件处理器
1143
+ Event._clear_all_handlers()
1144
+
1145
+ # 4. 清理僵尸线程
1146
+ logger.debug("[Uninit] 正在清理线程...")
1147
+ # SDK本身不创建线程,但可以记录可能的线程泄漏
1148
+ current_task = asyncio.current_task()
1149
+ logger.debug(f"[Uninit] 当前任务: {current_task}")
1150
+
1151
+ logger.info("[Uninit] SDK反初始化完成")
1152
+ return True
1153
+
1154
+ except Exception as e:
1155
+ logger.error(f"[Uninit] SDK反初始化失败: {e}")
1156
+ return False
1157
+
1158
+ async def restart() -> bool:
1159
+ """
1160
+ SDK重新启动
1161
+
1162
+ 执行完整的反初始化后再初始化过程
1163
+
1164
+ :return: bool 重新加载是否成功
1165
+ """
1166
+ logger.info("[Reload] 开始重新加载SDK...")
1167
+
1168
+ # 先执行反初始化
1169
+ if not await uninit():
1170
+ logger.error("[Reload] 反初始化失败,无法继续重新加载")
1171
+ return False
1172
+
1173
+ # 再执行初始化
1174
+ logger.info("[Reload] 开始重新初始化SDK...")
1175
+ if not await init():
1176
+ logger.error("[Reload] 初始化失败,请检查日志")
1177
+ return False
1178
+
1179
+ logger.info("[Reload] 正在启动适配器...")
1180
+ await adapter.startup()
1181
+
1182
+ logger.info("[Reload] 重新加载完成")
1183
+ return True
47
1184
 
1185
+ async def run(keep_running: bool = True) -> None:
1186
+ """
1187
+ 无头模式运行ErisPulse
1188
+
1189
+ 此方法提供了一种无需入口启动的方式,适用于与其它框架集成的场景
1190
+ """
1191
+ try:
1192
+ isInit = await init()
1193
+
1194
+ if not isInit:
1195
+ logger.error("ErisPulse 初始化失败,请检查日志")
1196
+ return
1197
+
1198
+ await adapter.startup()
1199
+
1200
+ if keep_running:
1201
+ # 保持程序运行
1202
+ await asyncio.Event().wait()
1203
+ except Exception as e:
1204
+ logger.error(e)
1205
+ finally:
1206
+ await module.unload()
1207
+ await adapter.shutdown()
48
1208
 
49
- # 导出SDK对象
50
- __all__ = [
51
- "sdk",
52
- "__version__",
53
- "__author__",
54
- "LazyModule",
55
- ]
1209
+ async def load_module(module_name: str) -> bool:
1210
+ """
1211
+ 手动加载指定模块
1212
+
1213
+ :param module_name: str 要加载的模块名称
1214
+ :return: bool 加载是否成功
1215
+
1216
+ {!--< tips >!--}
1217
+ 1. 可用于手动触发懒加载模块的初始化
1218
+ 2. 如果模块不存在或已加载会返回False
1219
+ 3. 对于需要异步初始化的模块,这是唯一的加载方式
1220
+ {!--< /tips >!--}
1221
+ """
1222
+ try:
1223
+ module_instance = getattr(sdk, module_name, None)
1224
+ if isinstance(module_instance, LazyModule):
1225
+ # 检查模块是否需要异步初始化
1226
+ if hasattr(module_instance, '_needs_async_init') and object.__getattribute__(module_instance, '_needs_async_init'):
1227
+ # 对于需要异步初始化的模块,执行完整异步初始化
1228
+ await module_instance._initialize()
1229
+ object.__setattr__(module_instance, '_needs_async_init', False) # 清除标志
1230
+ return True
1231
+ # 检查模块是否已经同步初始化但未完成异步部分
1232
+ elif (object.__getattribute__(module_instance, '_initialized') and
1233
+ object.__getattribute__(module_instance, '_is_base_module')):
1234
+ # 如果是BaseModule子类且已同步初始化,只需完成异步部分
1235
+ await module_instance._complete_async_init()
1236
+ return True
1237
+ else:
1238
+ # 触发懒加载模块的完整初始化
1239
+ await module_instance._initialize()
1240
+ return True
1241
+ elif module_instance is not None:
1242
+ logger.warning(f"模块 {module_name} 已经加载")
1243
+ return False
1244
+ else:
1245
+ logger.error(f"模块 {module_name} 不存在")
1246
+ return False
1247
+ except Exception as e:
1248
+ logger.error(f"加载模块 {module_name} 失败: {e}")
1249
+ return False
1250
+
1251
+ logger.debug("ErisPulse 正在挂载必要的入口方法")
1252
+ setattr(sdk, "init", init)
1253
+ setattr(sdk, "init_task", init_task)
1254
+ setattr(sdk, "load_module", load_module)
1255
+ setattr(sdk, "run", run)
1256
+ setattr(sdk, "restart", restart)
1257
+ setattr(sdk, "uninit", uninit)