ErisPulse 2.1.14.dev1__py3-none-any.whl → 2.1.15.dev3__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.
@@ -1,4 +1,3 @@
1
- # exceptions.py (新文件名)
2
1
  """
3
2
  ErisPulse 全局异常处理系统
4
3
 
@@ -8,71 +7,44 @@ ErisPulse 全局异常处理系统
8
7
  import sys
9
8
  import traceback
10
9
  import asyncio
10
+ import os
11
11
  from typing import Dict, Any, Type
12
- from .logger import logger
13
12
 
14
13
  class ExceptionHandler:
15
- """异常处理器类"""
16
-
17
14
  @staticmethod
18
15
  def format_exception(exc_type: Type[Exception], exc_value: Exception, exc_traceback: Any) -> str:
19
16
  """
20
- 格式化异常信息
21
-
22
17
  :param exc_type: 异常类型
23
18
  :param exc_value: 异常值
24
19
  :param exc_traceback: 追踪信息
25
20
  :return: 格式化后的异常信息
26
21
  """
27
- RED = '\033[91m'
28
- YELLOW = '\033[93m'
29
- BLUE = '\033[94m'
30
- RESET = '\033[0m'
31
-
32
- error_title = f"{RED}{exc_type.__name__}{RESET}: {YELLOW}{exc_value}{RESET}"
33
- traceback_lines = traceback.format_exception(exc_type, exc_value, exc_traceback)
22
+ tb_list = traceback.extract_tb(exc_traceback)
23
+ if tb_list:
24
+ last_frame = tb_list[-1]
25
+ filename = os.path.basename(last_frame.filename)
26
+ line_number = last_frame.lineno
27
+ function_name = last_frame.name
28
+ return f"ERROR: {filename}:{function_name}:{line_number}: {exc_type.__name__}: {exc_value}"
29
+ else:
30
+ return f"ERROR: {exc_type.__name__}: {exc_value}"
34
31
 
35
- colored_traceback = []
36
- for line in traceback_lines:
37
- if "File " in line and ", line " in line:
38
- parts = line.split(', line ')
39
- colored_line = f"{BLUE}{parts[0]}{RESET}, line {parts[1]}"
40
- colored_traceback.append(colored_line)
41
- else:
42
- colored_traceback.append(f"{RED}{line}{RESET}")
43
-
44
- return f"""
45
- {error_title}
46
- {RED}Traceback:{RESET}
47
- {''.join(colored_traceback)}"""
48
-
49
32
  @staticmethod
50
33
  def format_async_exception(exception: Exception) -> str:
51
34
  """
52
- 格式化异步异常信息
53
-
54
35
  :param exception: 异常对象
55
36
  :return: 格式化后的异常信息
56
37
  """
57
- RED = '\033[91m'
58
- YELLOW = '\033[93m'
59
- BLUE = '\033[94m'
60
- RESET = '\033[0m'
38
+ if exception.__traceback__:
39
+ tb_list = traceback.extract_tb(exception.__traceback__)
40
+ if tb_list:
41
+ last_frame = tb_list[-1]
42
+ filename = os.path.basename(last_frame.filename)
43
+ line_number = last_frame.lineno
44
+ function_name = last_frame.name
45
+ return f"ERROR: {filename}:{function_name}:{line_number}: {type(exception).__name__}: {exception}"
61
46
 
62
- tb = ''.join(traceback.format_exception(type(exception), exception, exception.__traceback__))
63
-
64
- colored_tb = []
65
- for line in tb.split('\n'):
66
- if "File " in line and ", line " in line:
67
- parts = line.split(', line ')
68
- colored_line = f"{BLUE}{parts[0]}{RESET}, line {parts[1]}"
69
- colored_tb.append(colored_line)
70
- else:
71
- colored_tb.append(f"{RED}{line}{RESET}")
72
-
73
- return f"""{RED}{type(exception).__name__}{RESET}: {YELLOW}{exception}{RESET}
74
- {RED}Traceback:{RESET}
75
- {''.join(colored_tb)}"""
47
+ return f"ERROR: {type(exception).__name__}: {exception}"
76
48
 
77
49
  def global_exception_handler(exc_type: Type[Exception], exc_value: Exception, exc_traceback: Any) -> None:
78
50
  """
@@ -83,13 +55,13 @@ def global_exception_handler(exc_type: Type[Exception], exc_value: Exception, ex
83
55
  :param exc_traceback: 追踪信息
84
56
  """
85
57
  try:
86
- formatted_error = ExceptionHandler.format_exception(exc_type, exc_value, exc_traceback)
87
- sys.stderr.write(formatted_error)
88
- # 同时记录到日志系统
89
- logger.error(f"未捕获异常: {exc_type.__name__}: {exc_value}")
90
- except Exception:
91
- # 防止异常处理过程中出现异常
92
- sys.stderr.write(f"Uncaught exception: {exc_type.__name__}: {exc_value}\n")
58
+ from ErisPulse import logger
59
+ err_logger = logger.error
60
+ except ImportError:
61
+ err_logger = sys.stderr.write
62
+
63
+ formatted_error = ExceptionHandler.format_exception(exc_type, exc_value, exc_traceback)
64
+ err_logger(formatted_error)
93
65
 
94
66
  def async_exception_handler(loop: asyncio.AbstractEventLoop, context: Dict[str, Any]) -> None:
95
67
  """
@@ -98,39 +70,39 @@ def async_exception_handler(loop: asyncio.AbstractEventLoop, context: Dict[str,
98
70
  :param loop: 事件循环
99
71
  :param context: 上下文字典
100
72
  """
101
- RED = '\033[91m'
102
- YELLOW = '\033[93m'
103
- RESET = '\033[0m'
73
+ try:
74
+ from ErisPulse import logger
75
+ err_logger = logger.error
76
+ except ImportError:
77
+ err_logger = sys.stderr.write
104
78
 
105
79
  exception = context.get('exception')
106
80
  if exception:
107
81
  try:
108
82
  formatted_error = ExceptionHandler.format_async_exception(exception)
109
- sys.stderr.write(formatted_error)
110
- # 同时记录到日志系统
111
- logger.error(f"异步异常: {type(exception).__name__}: {exception}")
83
+ err_logger(formatted_error + '\n')
112
84
  except Exception:
113
- sys.stderr.write(f"{RED}Async Error{RESET}: {YELLOW}{exception}{RESET}\n")
85
+ err_logger(f"ERROR: 捕捉器发生错误,原始异常信息:\n\n{exception}\n\n" + traceback.format_exc())
114
86
  else:
115
- msg = context.get('message', 'Unknown async error')
116
- sys.stderr.write(f"{RED}Async Error{RESET}: {YELLOW}{msg}{RESET}\n")
117
- logger.error(f"异步错误: {msg}")
118
-
119
- # 注册全局异常处理器
120
- sys.excepthook = global_exception_handler
121
- try:
122
- asyncio.get_event_loop().set_exception_handler(async_exception_handler)
123
- except RuntimeError:
124
- # 如果还没有事件循环,则在创建时设置
125
- pass
87
+ msg = context.get('message', '未知异步错误')
88
+ err_logger(f"ERROR: 未处理的异步错误: {msg}\n")
126
89
 
127
- # 提供一个函数用于在创建新事件循环时设置异常处理器
128
- def setup_async_exception_handler(loop: asyncio.AbstractEventLoop = None) -> None:
90
+ def setup_async_loop(loop: asyncio.AbstractEventLoop = None) -> None:
129
91
  """
130
- 设置异步异常处理器
92
+ 为指定的事件循环设置异常处理器
131
93
 
132
- :param loop: 事件循环,如果为None则使用当前事件循环
94
+ :param loop: 事件循环实例,如果为None则使用当前事件循环
133
95
  """
134
96
  if loop is None:
135
- loop = asyncio.get_event_loop()
136
- loop.set_exception_handler(async_exception_handler)
97
+ try:
98
+ loop = asyncio.get_running_loop()
99
+ except RuntimeError:
100
+ loop = asyncio.get_event_loop()
101
+
102
+ loop.set_exception_handler(async_exception_handler)
103
+
104
+ sys.excepthook = global_exception_handler
105
+ try:
106
+ asyncio.get_event_loop().set_exception_handler(async_exception_handler)
107
+ except RuntimeError:
108
+ pass
ErisPulse/Core/logger.py CHANGED
@@ -56,6 +56,10 @@ class Logger:
56
56
  """
57
57
  if limit > 0:
58
58
  self._max_logs = limit
59
+ # 更新所有已存在的日志列表大小
60
+ for module_name in self._logs:
61
+ while len(self._logs[module_name]) > self._max_logs:
62
+ self._logs[module_name].pop(0)
59
63
  return True
60
64
  else:
61
65
  self._logger.warning("日志存储上限必须大于0。")
@@ -174,7 +178,7 @@ class Logger:
174
178
  self._logs[ModuleName].append(msg)
175
179
 
176
180
  def _setup_config(self):
177
- from .config import get_logger_config
181
+ from .erispulse_config import get_logger_config
178
182
  logger_config = get_logger_config()
179
183
  if "level" in logger_config:
180
184
  self.set_level(logger_config["level"])
@@ -198,6 +202,20 @@ class Logger:
198
202
  module_name = "ErisPulse"
199
203
  return module_name
200
204
 
205
+ def get_child(self, child_name: str = None):
206
+ """
207
+ 获取子日志记录器
208
+
209
+ :param child_name: 子模块名称(可选)
210
+ :return: LoggerChild 子日志记录器实例
211
+ """
212
+ caller_module = self._get_caller()
213
+ if child_name:
214
+ full_module_name = f"{caller_module}.{child_name}"
215
+ else:
216
+ full_module_name = caller_module
217
+ return LoggerChild(self, full_module_name)
218
+
201
219
  def debug(self, msg, *args, **kwargs):
202
220
  caller_module = self._get_caller()
203
221
  if self._get_effective_level(caller_module) <= logging.DEBUG:
@@ -229,4 +247,63 @@ class Logger:
229
247
  self._logger.critical(f"[{caller_module}] {msg}", *args, **kwargs)
230
248
  raise Exception(msg)
231
249
 
232
- logger = Logger()
250
+
251
+ class LoggerChild:
252
+ """
253
+ 子日志记录器
254
+
255
+ 用于创建具有特定名称的子日志记录器,仅改变模块名称,其他功能全部委托给父日志记录器
256
+ """
257
+
258
+ def __init__(self, parent_logger: Logger, name: str):
259
+ """
260
+ 初始化子日志记录器
261
+
262
+ :param parent_logger: 父日志记录器实例
263
+ :param name: 子日志记录器名称
264
+ """
265
+ self._parent = parent_logger
266
+ self._name = name
267
+
268
+ def debug(self, msg, *args, **kwargs):
269
+ if self._parent._get_effective_level(self._name.split('.')[0]) <= logging.DEBUG:
270
+ self._parent._save_in_memory(self._name, msg)
271
+ self._parent._logger.debug(f"[{self._name}] {msg}", *args, **kwargs)
272
+
273
+ def info(self, msg, *args, **kwargs):
274
+ if self._parent._get_effective_level(self._name.split('.')[0]) <= logging.INFO:
275
+ self._parent._save_in_memory(self._name, msg)
276
+ self._parent._logger.info(f"[{self._name}] {msg}", *args, **kwargs)
277
+
278
+ def warning(self, msg, *args, **kwargs):
279
+ if self._parent._get_effective_level(self._name.split('.')[0]) <= logging.WARNING:
280
+ self._parent._save_in_memory(self._name, msg)
281
+ self._parent._logger.warning(f"[{self._name}] {msg}", *args, **kwargs)
282
+
283
+ def error(self, msg, *args, **kwargs):
284
+ if self._parent._get_effective_level(self._name.split('.')[0]) <= logging.ERROR:
285
+ self._parent._save_in_memory(self._name, msg)
286
+ self._parent._logger.error(f"[{self._name}] {msg}", *args, **kwargs)
287
+
288
+ def critical(self, msg, *args, **kwargs):
289
+ if self._parent._get_effective_level(self._name.split('.')[0]) <= logging.CRITICAL:
290
+ self._parent._save_in_memory(self._name, msg)
291
+ self._parent._logger.critical(f"[{self._name}] {msg}", *args, **kwargs)
292
+ raise Exception(msg)
293
+
294
+ def get_child(self, child_name: str):
295
+ """
296
+ 获取子日志记录器的子记录器
297
+
298
+ :param child_name: 子模块名称
299
+ :return: LoggerChild 子日志记录器实例
300
+ """
301
+ full_child_name = f"{self._name}.{child_name}"
302
+ return LoggerChild(self._parent, full_child_name)
303
+
304
+
305
+ logger = Logger()
306
+
307
+ __all__ = [
308
+ "logger"
309
+ ]
ErisPulse/Core/mods.py CHANGED
@@ -30,8 +30,8 @@ class ModuleManager:
30
30
  DEFAULT_STATUS_PREFIX = "erispulse.data.modules.status:"
31
31
 
32
32
  def __init__(self):
33
- from .env import env
34
- self.env = env
33
+ from .storage import storage
34
+ self.storage = storage
35
35
  self._ensure_prefixes()
36
36
 
37
37
  def _ensure_prefixes(self) -> None:
@@ -39,10 +39,10 @@ class ModuleManager:
39
39
  {!--< internal-use >!--}
40
40
  确保模块前缀配置存在
41
41
  """
42
- if not self.env.get("erispulse.system.module_prefix"):
43
- self.env.set("erispulse.system.module_prefix", self.DEFAULT_MODULE_PREFIX)
44
- if not self.env.get("erispulse.system.status_prefix"):
45
- self.env.set("erispulse.system.status_prefix", self.DEFAULT_STATUS_PREFIX)
42
+ if not self.storage.get("erispulse.system.module_prefix"):
43
+ self.storage.set("erispulse.system.module_prefix", self.DEFAULT_MODULE_PREFIX)
44
+ if not self.storage.get("erispulse.system.status_prefix"):
45
+ self.storage.set("erispulse.system.status_prefix", self.DEFAULT_STATUS_PREFIX)
46
46
 
47
47
  @property
48
48
  def module_prefix(self) -> str:
@@ -51,7 +51,7 @@ class ModuleManager:
51
51
 
52
52
  :return: 模块数据前缀字符串
53
53
  """
54
- return self.env.get("erispulse.system.module_prefix")
54
+ return self.storage.get("erispulse.system.module_prefix")
55
55
 
56
56
  @property
57
57
  def status_prefix(self) -> str:
@@ -60,7 +60,7 @@ class ModuleManager:
60
60
 
61
61
  :return: 模块状态前缀字符串
62
62
  """
63
- return self.env.get("erispulse.system.status_prefix")
63
+ return self.storage.get("erispulse.system.status_prefix")
64
64
 
65
65
  def set_module_status(self, module_name: str, status: bool) -> None:
66
66
  """
@@ -76,7 +76,7 @@ class ModuleManager:
76
76
  >>> mods.set_module_status("MyModule", False)
77
77
  """
78
78
  from .logger import logger
79
- self.env.set(f"{self.status_prefix}{module_name}", bool(status))
79
+ self.storage.set(f"{self.status_prefix}{module_name}", bool(status))
80
80
  logger.debug(f"模块 {module_name} 状态已设置为 {status}")
81
81
 
82
82
  def get_module_status(self, module_name: str) -> bool:
@@ -90,7 +90,7 @@ class ModuleManager:
90
90
  >>> if mods.get_module_status("MyModule"):
91
91
  >>> print("模块已启用")
92
92
  """
93
- status = self.env.get(f"{self.status_prefix}{module_name}", True)
93
+ status = self.storage.get(f"{self.status_prefix}{module_name}", True)
94
94
  if isinstance(status, str):
95
95
  return status.lower() not in ('false', '0', 'no', 'off')
96
96
  return bool(status)
@@ -108,7 +108,7 @@ class ModuleManager:
108
108
  >>> "description": "我的模块",
109
109
  >>> })
110
110
  """
111
- self.env.set(f"{self.module_prefix}{module_name}", module_info)
111
+ self.storage.set(f"{self.module_prefix}{module_name}", module_info)
112
112
 
113
113
  def get_module(self, module_name: str) -> Optional[Dict[str, Any]]:
114
114
  """
@@ -122,7 +122,7 @@ class ModuleManager:
122
122
  >>> if module_info:
123
123
  >>> print(f"模块版本: {module_info.get('version')}")
124
124
  """
125
- return self.env.get(f"{self.module_prefix}{module_name}")
125
+ return self.storage.get(f"{self.module_prefix}{module_name}")
126
126
 
127
127
  def set_all_modules(self, modules_info: Dict[str, Dict[str, Any]]) -> None:
128
128
  """
@@ -151,7 +151,7 @@ class ModuleManager:
151
151
  >>> print(f"{name}: {info.get('status')}")
152
152
  """
153
153
  modules_info = {}
154
- all_keys = self.env.get_all_keys()
154
+ all_keys = self.storage.get_all_keys()
155
155
  prefix_len = len(self.module_prefix)
156
156
 
157
157
  for key in all_keys:
@@ -185,9 +185,9 @@ class ModuleManager:
185
185
  module_key = f"{self.module_prefix}{module_name}"
186
186
  status_key = f"{self.status_prefix}{module_name}"
187
187
 
188
- if self.env.get(module_key) is not None:
189
- self.env.delete(module_key)
190
- self.env.delete(status_key)
188
+ if self.storage.get(module_key) is not None:
189
+ self.storage.delete(module_key)
190
+ self.storage.delete(status_key)
191
191
  return True
192
192
  return False
193
193
 
@@ -208,12 +208,16 @@ class ModuleManager:
208
208
  if module_prefix:
209
209
  if not module_prefix.endswith(':'):
210
210
  module_prefix += ':'
211
- self.env.set("erispulse.system.module_prefix", module_prefix)
211
+ self.storage.set("erispulse.system.module_prefix", module_prefix)
212
212
 
213
213
  if status_prefix:
214
214
  if not status_prefix.endswith(':'):
215
215
  status_prefix += ':'
216
- self.env.set("erispulse.system.status_prefix", status_prefix)
216
+ self.storage.set("erispulse.system.status_prefix", status_prefix)
217
217
 
218
218
 
219
219
  mods = ModuleManager()
220
+
221
+ __all__ = [
222
+ "mods",
223
+ ]
ErisPulse/Core/router.py CHANGED
@@ -254,4 +254,9 @@ class RouterManager:
254
254
  router = RouterManager()
255
255
 
256
256
  # 兼容性实例
257
- adapter_server = router
257
+ adapter_server = router
258
+
259
+ __all__ = [
260
+ "router",
261
+ "adapter_server"
262
+ ]