ErisPulse 2.3.9.dev3__tar.gz → 2.4.0.dev2__tar.gz

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 (119) hide show
  1. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/PKG-INFO +2 -1
  2. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/README.md +2 -1
  3. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/pyproject.toml +1 -1
  4. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Bases/adapter.py +166 -118
  5. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Bases/adapter.pyi +22 -10
  6. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Bases/manager.py +38 -40
  7. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Bases/manager.pyi +5 -5
  8. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Bases/module.py +22 -20
  9. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Bases/module.pyi +4 -3
  10. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/__init__.py +15 -0
  11. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/__init__.pyi +2 -0
  12. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/base.py +32 -24
  13. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/base.pyi +2 -1
  14. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/command.py +187 -150
  15. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/command.pyi +9 -8
  16. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/message.py +43 -29
  17. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/message.pyi +2 -1
  18. erispulse-2.4.0.dev2/src/ErisPulse/Core/Event/message_builder.py +270 -0
  19. erispulse-2.4.0.dev2/src/ErisPulse/Core/Event/message_builder.pyi +163 -0
  20. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/meta.py +39 -28
  21. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/meta.pyi +2 -1
  22. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/notice.py +47 -34
  23. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/notice.pyi +2 -1
  24. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/request.py +32 -23
  25. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/request.pyi +2 -1
  26. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/session_type.py +91 -81
  27. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/session_type.pyi +27 -21
  28. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/wrapper.py +341 -108
  29. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/wrapper.pyi +142 -18
  30. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/__init__.py +2 -0
  31. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/__init__.pyi +1 -0
  32. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/adapter.py +370 -118
  33. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/adapter.pyi +80 -12
  34. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/config.py +30 -24
  35. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/config.pyi +2 -2
  36. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/lifecycle.py +65 -47
  37. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/lifecycle.pyi +4 -3
  38. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/logger.py +42 -102
  39. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/logger.pyi +22 -41
  40. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/module.py +128 -125
  41. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/module.pyi +16 -16
  42. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/router.py +123 -103
  43. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/router.pyi +12 -11
  44. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/storage.py +174 -146
  45. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/storage.pyi +18 -8
  46. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/finders/bases/finder.py +51 -50
  47. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/finders/bases/finder.pyi +2 -1
  48. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/loaders/adapter.py +87 -79
  49. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/loaders/adapter.pyi +14 -14
  50. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/loaders/bases/loader.py +48 -45
  51. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/loaders/bases/loader.pyi +1 -1
  52. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/loaders/module.py +417 -280
  53. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/loaders/module.pyi +19 -19
  54. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/loaders/strategy.py +29 -29
  55. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/loaders/strategy.pyi +3 -3
  56. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/runtime/frame_config.py +4 -4
  57. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/runtime/frame_config.pyi +2 -2
  58. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/sdk.py +5 -4
  59. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/.gitignore +0 -0
  60. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/LICENSE +0 -0
  61. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/__init__.py +0 -0
  62. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/__init__.pyi +0 -0
  63. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/base.py +0 -0
  64. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/base.pyi +0 -0
  65. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/cli.py +0 -0
  66. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/cli.pyi +0 -0
  67. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/__init__.py +0 -0
  68. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/__init__.pyi +0 -0
  69. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/init.py +0 -0
  70. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/init.pyi +0 -0
  71. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/install.py +0 -0
  72. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/install.pyi +0 -0
  73. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/list.py +0 -0
  74. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/list.pyi +0 -0
  75. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/list_remote.py +0 -0
  76. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/list_remote.pyi +0 -0
  77. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/run.py +0 -0
  78. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/run.pyi +0 -0
  79. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/self_update.py +0 -0
  80. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/self_update.pyi +0 -0
  81. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/uninstall.py +0 -0
  82. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/uninstall.pyi +0 -0
  83. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/upgrade.py +0 -0
  84. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/upgrade.pyi +0 -0
  85. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/console.py +0 -0
  86. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/console.pyi +0 -0
  87. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/registry.py +0 -0
  88. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/registry.pyi +0 -0
  89. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/utils/__init__.py +0 -0
  90. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/utils/__init__.pyi +0 -0
  91. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/utils/package_manager.py +0 -0
  92. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/utils/package_manager.pyi +0 -0
  93. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Bases/__init__.py +0 -0
  94. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Bases/__init__.pyi +0 -0
  95. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/__init__.py +0 -0
  96. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/__init__.pyi +0 -0
  97. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/__main__.py +0 -0
  98. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/__main__.pyi +0 -0
  99. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/finders/__init__.py +0 -0
  100. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/finders/__init__.pyi +0 -0
  101. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/finders/adapter.py +0 -0
  102. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/finders/adapter.pyi +0 -0
  103. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/finders/bases/__init__.py +0 -0
  104. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/finders/bases/__init__.pyi +0 -0
  105. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/finders/cli.py +0 -0
  106. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/finders/cli.pyi +0 -0
  107. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/finders/module.py +0 -0
  108. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/finders/module.pyi +0 -0
  109. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/loaders/__init__.py +0 -0
  110. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/loaders/__init__.pyi +0 -0
  111. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/loaders/bases/__init__.py +0 -0
  112. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/loaders/bases/__init__.pyi +0 -0
  113. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/runtime/__init__.py +0 -0
  114. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/runtime/__init__.pyi +0 -0
  115. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/runtime/cleanup.py +0 -0
  116. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/runtime/cleanup.pyi +0 -0
  117. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/runtime/exceptions.py +0 -0
  118. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/runtime/exceptions.pyi +0 -0
  119. {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/sdk.pyi +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ErisPulse
3
- Version: 2.3.9.dev3
3
+ Version: 2.4.0.dev2
4
4
  Summary: ErisPulse 是一个模块化、可扩展的异步 Python SDK 框架,主要用于构建高效、可维护的机器人应用程序。
5
5
  Author-email: ErisDev <erisdev@88.com>
6
6
  Maintainer-email: "艾莉丝·格雷拉特(WSu2059)" <wsu2059@qq.com>
@@ -205,6 +205,7 @@ epsdk run main.py --reload
205
205
  - [OneBot12](https://github.com/ErisPulse/ErisPulse-OneBot12Adapter) - OneBot12 标准
206
206
  - [邮件](https://github.com/ErisPulse/ErisPulse-EmailAdapter) - 邮件收发处理
207
207
  - [沙箱](https://github.com/ErisPulse/ErisPulse-SandboxAdapter) - 网页调试界面,无需接入实际平台
208
+ - [Kook](https://github.com/shanfishapp/ErisPulse-KookAdapter) - Kook(开黑啦)即时通讯平台
208
209
 
209
210
  查看 [适配器详情介绍](docs/zh-CN/platform-guide/README.md)
210
211
 
@@ -144,7 +144,8 @@ epsdk run main.py --reload
144
144
  - [OneBot11](https://github.com/ErisPulse/ErisPulse-OneBot11Adapter) - 通用机器人接口标准
145
145
  - [OneBot12](https://github.com/ErisPulse/ErisPulse-OneBot12Adapter) - OneBot12 标准
146
146
  - [邮件](https://github.com/ErisPulse/ErisPulse-EmailAdapter) - 邮件收发处理
147
- - [沙箱](https://github.com/ErisPulse/ErisPulse-SandboxAdapter) - 网页调试界面,无需接入实际平台
147
+ - [沙箱](https://github.com/ErisPulse/ErisPulse-SandboxAdapter) - 网页调试界面,无需接入实际平台
148
+ - [Kook](https://github.com/shanfishapp/ErisPulse-KookAdapter) - Kook(开黑啦)即时通讯平台
148
149
 
149
150
  查看 [适配器详情介绍](docs/zh-CN/platform-guide/README.md)
150
151
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "ErisPulse"
7
- version = "2.3.9-dev.3"
7
+ version = "2.4.0-dev.2"
8
8
  description = "ErisPulse 是一个模块化、可扩展的异步 Python SDK 框架,主要用于构建高效、可维护的机器人应用程序。"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -10,27 +10,33 @@ ErisPulse 适配器基础模块
10
10
  """
11
11
 
12
12
  import asyncio
13
- from typing import (
14
- Any, Optional,
15
- Union, Awaitable
16
- )
13
+ from abc import ABC, abstractmethod
14
+ from typing import Any
15
+ from collections.abc import Awaitable
16
+
17
17
 
18
18
  class SendDSL:
19
19
  """
20
20
  消息发送DSL基类
21
-
21
+
22
22
  用于实现 Send.To(...).Func(...) 风格的链式调用接口
23
-
23
+
24
24
  {!--< tips >!--}
25
25
  1. 子类应实现具体的消息发送方法(如Text, Image等)
26
26
  2. 通过__getattr__实现动态方法调用
27
27
  {!--< /tips >!--}
28
28
  """
29
-
30
- def __init__(self, adapter: 'BaseAdapter', target_type: Optional[str] = None, target_id: Optional[str] = None, account_id: Optional[str] = None):
29
+
30
+ def __init__(
31
+ self,
32
+ adapter: "BaseAdapter",
33
+ target_type: str | None = None,
34
+ target_id: str | None = None,
35
+ account_id: str | None = None,
36
+ ):
31
37
  """
32
38
  初始化DSL发送器
33
-
39
+
34
40
  :param adapter: 所属适配器实例
35
41
  :param target_type: 目标类型(可选)
36
42
  :param target_id: 目标ID(可选)
@@ -41,14 +47,14 @@ class SendDSL:
41
47
  self._target_id = target_id
42
48
  self._target_to = target_id
43
49
  self._account_id = account_id
44
-
50
+
45
51
  def __getattr__(self, name: str):
46
52
  """
47
53
  动态属性访问处理,实现大小写不敏感调用
48
-
54
+
49
55
  1. 如果找到匹配的方法(忽略大小写),返回该方法
50
56
  2. 如果没找到,打印警告并抛出 AttributeError
51
-
57
+
52
58
  :param name: 属性名
53
59
  :return: 匹配的方法或属性
54
60
  :raises AttributeError: 当属性不存在时抛出
@@ -56,9 +62,9 @@ class SendDSL:
56
62
  # 检查所有实际存在的方法
57
63
  for attr_name in dir(self.__class__):
58
64
  # 跳过特殊方法
59
- if attr_name.startswith('_'):
65
+ if attr_name.startswith("_"):
60
66
  continue
61
-
67
+
62
68
  # 大小写不敏感匹配
63
69
  if attr_name.lower() == name.lower():
64
70
  # 返回实际的方法绑定到当前实例
@@ -66,65 +72,76 @@ class SendDSL:
66
72
  if callable(attr):
67
73
  return attr.__get__(self, self.__class__)
68
74
  return attr
69
-
75
+
70
76
  # 没有找到匹配的方法,打印警告
71
- from .. import logger
77
+ from ..logger import logger
78
+
72
79
  logger.warning(
73
- f"平台 {self._adapter.__class__.__name__} "
74
- f"未实现 {name} 发送方法"
80
+ f"平台 {self._adapter.__class__.__name__} 未实现 {name} 发送方法"
75
81
  )
76
-
82
+
77
83
  # 抛出 AttributeError,这样 hasattr() 能正常工作
78
- raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'")
79
-
80
- def At(self, **kwargs):
81
- from .. import logger
82
- logger.warning(
83
- f"平台 {self._adapter.__class__.__name__} 未实现 At 方法,该修饰方法将被忽略。"
84
- f"参数: {kwargs}"
84
+ raise AttributeError(
85
+ f"'{self.__class__.__name__}' object has no attribute '{name}'"
85
86
  )
86
- return self.__class__(self._adapter, self._target_type, self._target_id, self._account_id)
87
- def Reply(self, **kwargs):
88
- from .. import logger
87
+
88
+ def _unimplemented_modifier(self, method_name: str, **kwargs) -> "SendDSL":
89
+ """处理未实现的修饰方法,记录警告并返回自身以保持链式调用"""
90
+ from ..logger import logger
91
+
89
92
  logger.warning(
90
- f"平台 {self._adapter.__class__.__name__} 未实现 Reply 方法,该修饰方法将被忽略。"
93
+ f"平台 {self._adapter.__class__.__name__} 未实现 {method_name} 方法,该修饰方法将被忽略。"
91
94
  f"参数: {kwargs}"
92
95
  )
93
- return self.__class__(self._adapter, self._target_type, self._target_id, self._account_id)
96
+ return self
97
+
98
+ def At(self, **kwargs):
99
+ return self._unimplemented_modifier("At", **kwargs)
100
+
101
+ def Reply(self, **kwargs):
102
+ return self._unimplemented_modifier("Reply", **kwargs)
103
+
94
104
  def AtAll(self, **kwargs):
95
- from .. import logger
96
- logger.warning(
97
- f"平台 {self._adapter.__class__.__name__} 未实现 AtAll 方法,该修饰方法将被忽略。"
98
- f"参数: {kwargs}"
99
- )
100
- return self.__class__(self._adapter, self._target_type, self._target_id, self._account_id)
101
- def Raw_ob12(self, **kwargs):
102
- from .. import logger
103
- logger.warning(
104
- f"平台 {self._adapter.__class__.__name__} 未实现 Raw_ob12 方法,该修饰方法将被忽略。"
105
- f"参数: {kwargs}"
106
- )
107
- return self.__class__(self._adapter, self._target_type, self._target_id, self._account_id)
108
- def Raw_json(self, **kwargs):
109
- from .. import logger
110
- logger.warning(
111
- f"平台 {self._adapter.__class__.__name__} 未实现 Raw_json 方法,该修饰方法将被忽略。"
112
- f"参数: {kwargs}"
105
+ return self._unimplemented_modifier("AtAll", **kwargs)
106
+
107
+ def Raw_ob12(self, message, **kwargs):
108
+ """
109
+ 发送 OneBot12 格式消息段(必须由适配器子类重写)
110
+
111
+ :param message: OneBot12 消息段列表或单个消息段
112
+ :param kwargs: 其他参数
113
+ :return: asyncio.Task
114
+ """
115
+ from ..logger import logger
116
+
117
+ logger.error(
118
+ f"平台 {self._adapter.__class__.__name__} 未实现 Raw_ob12 方法,"
119
+ f"消息未被发送。适配器必须实现此方法以支持 OneBot12 消息段发送。"
113
120
  )
114
- return self.__class__(self._adapter, self._target_type, self._target_id, self._account_id)
115
-
116
- def To(self, target_type: str = None, target_id: Union[str, int] = None) -> 'SendDSL':
121
+
122
+ async def _not_impl():
123
+ return {
124
+ "status": "failed",
125
+ "retcode": 10002,
126
+ "data": None,
127
+ "message_id": "",
128
+ "message": f"平台 {self._adapter.__class__.__name__} 未实现 Raw_ob12 方法",
129
+ }
130
+
131
+ return asyncio.create_task(_not_impl())
132
+
133
+ def To(self, target_type: str = None, target_id: str | int = None) -> "SendDSL":
117
134
  """
118
135
  设置消息目标
119
-
136
+
120
137
  支持自动类型转换:
121
138
  - 当 target_type 为 "private" 时,自动转换为 "user"
122
139
  - 当只提供 target_id(字符串或数字)时,默认推断为 "user"
123
-
140
+
124
141
  :param target_type: 目标类型(可选)
125
142
  :param target_id: 目标ID(可选)
126
143
  :return: SendDSL实例
127
-
144
+
128
145
  :example:
129
146
  >>> # 标准用法
130
147
  >>> adapter.Send.To("user", "123").Text("Hello")
@@ -134,12 +151,12 @@ class SendDSL:
134
151
  >>> adapter.Send.To("123").Text("Hello")
135
152
  """
136
153
  from ..Event.session_type import is_standard_type
137
-
154
+
138
155
  # 处理简化形式:只提供一个参数作为 target_id
139
156
  if target_id is None and target_type is not None:
140
157
  target_id = target_type
141
158
  target_type = None
142
-
159
+
143
160
  # 如果没有明确指定 target_type,尝试推断
144
161
  if target_type is None:
145
162
  # 将 target_id 作为字符串处理
@@ -147,45 +164,50 @@ class SendDSL:
147
164
  # 默认推断为 user(对应 private)
148
165
  # 这里我们假设如果只提供 ID,通常是发送给用户
149
166
  target_type = "user"
150
-
167
+
151
168
  # 自动转换 private → user
152
169
  if target_type == "private":
153
170
  target_type = "user"
154
-
171
+
155
172
  return self.__class__(self._adapter, target_type, target_id, self._account_id)
156
173
 
157
- def Using(self, account_id: Union[str, int]) -> 'SendDSL':
174
+ def Using(self, account_id: str | int) -> "SendDSL":
158
175
  """
159
176
  设置发送账号
160
-
177
+
161
178
  :param _account_id: 发送账号
162
179
  :return: SendDSL实例
163
-
180
+
164
181
  :example:
165
182
  >>> adapter.Send.Using("bot1").To("123").Text("Hello")
166
183
  >>> adapter.Send.To("123").Using("bot1").Text("Hello") # 支持乱序
167
184
  """
168
- return self.__class__(self._adapter, self._target_type, self._target_id, account_id)
169
-
170
- def Account(self, account_id: Union[str, int]) -> 'SendDSL':
185
+ return self.__class__(
186
+ self._adapter, self._target_type, self._target_id, account_id
187
+ )
188
+
189
+ def Account(self, account_id: str | int) -> "SendDSL":
171
190
  """
172
191
  设置发送账号
173
-
192
+
174
193
  :param _account_id: 发送账号
175
194
  :return: SendDSL实例
176
-
195
+
177
196
  :example:
178
197
  >>> adapter.Send.Account("bot1").To("123").Text("Hello")
179
198
  >>> adapter.Send.To("123").Account("bot1").Text("Hello") # 支持乱序
180
199
  """
181
- return self.__class__(self._adapter, self._target_type, self._target_id, account_id)
200
+ return self.__class__(
201
+ self._adapter, self._target_type, self._target_id, account_id
202
+ )
182
203
 
183
- class BaseAdapter:
204
+
205
+ class BaseAdapter(ABC):
184
206
  """
185
207
  适配器基类
186
-
208
+
187
209
  提供与外部平台交互的标准接口,子类必须实现必要方法
188
-
210
+
189
211
  {!--< tips >!--}
190
212
  1. 必须实现call_api, start和shutdown方法
191
213
  2. 可以自定义Send类实现平台特定的消息发送逻辑
@@ -193,66 +215,69 @@ class BaseAdapter:
193
215
  4. 支持OneBot12协议的事件处理
194
216
  {!--< /tips >!--}
195
217
  """
196
-
218
+
197
219
  class Send(SendDSL):
198
220
  """
199
221
  消息发送DSL实现
200
-
222
+
201
223
  {!--< tips >!--}
202
224
  1. 子类可以重写Text方法提供平台特定实现
203
225
  2. 可以添加新的消息类型(如Image, Voice等)
204
226
  {!--< /tips >!--}
205
227
  """
206
-
228
+
207
229
  def Example(self, text: str) -> Awaitable[Any]:
208
230
  """
209
231
  示例消息发送方法
210
-
232
+
211
233
  :param text: 文本内容
212
234
  :return: 异步任务
213
235
  :example:
214
236
  >>> await adapter.Send.To("123").Example("Hello")
215
237
  """
238
+ mock_response = {
239
+ "status": "ok",
240
+ "retcode": 0,
241
+ "data": {"message_id": "1234567890", "time": 1755801512},
242
+ "message_id": "1234567890",
243
+ "message": "",
244
+ "echo": None,
245
+ "example_raw": {
246
+ "result": "success",
247
+ },
248
+ }
216
249
 
217
- text = {
218
- "status": "ok",
219
- "retcode": 0,
220
- "data": {
221
- "message_id": "1234567890",
222
- "time": 1755801512
223
- },
224
- "message_id": "1234567890",
225
- "message": "",
226
- "echo": None,
227
- "example_raw": {
228
- "result": "success",
229
- }
230
- }
231
250
  async def _send_example():
232
- from .. import logger
251
+ from ..logger import logger
252
+
233
253
  logger.info(f"发送示例消息: {text}")
234
- return text
254
+ return mock_response
255
+
235
256
  return asyncio.create_task(_send_example())
236
257
 
237
258
  def Raw_ob12(self, message, **kwargs: Any) -> Awaitable[Any]:
238
259
  """
239
- 发送原始 OneBot12 格式的消息
240
-
241
- 注意:此方法为可选实现,适配器可以根据平台特性决定是否重写。
242
- 默认实现仅记录警告,不实际发送消息。
243
-
260
+ 发送 OneBot12 格式消息段(必须由适配器子类重写)
261
+
262
+ 此方法是反向转换(OneBot12 → 平台)的统一入口,适配器必须重写此方法。
263
+ 未重写时,基类默认实现会记录错误日志并返回标准错误响应。
264
+
244
265
  :param message: OneBot12 格式的消息段数组或单个消息段
266
+ [
267
+ {"type": "text", "data": {"text": "Hello"}},
268
+ {"type": "image", "data": {"file": "https://..."}},
269
+ ]
245
270
  :param kwargs: 其他参数
246
- :return: 异步任务
247
-
271
+ :return: asyncio.Task,await 后返回标准响应格式
272
+
248
273
  :example:
249
274
  >>> # 用户调用
250
275
  >>> await adapter.Send.To("user", "123").Raw_ob12([
251
276
  >>> {"type": "text", "data": {"text": "Hello"}},
252
- >>> {"type": "image", "data": {"file_id": "xxx"}}
277
+ >>> {"type": "image", "data": {"file": "https://..."}}
253
278
  >>> ])
254
-
255
- >>> # 适配器子类重写示例(可选)
279
+
280
+ >>> # 适配器子类重写示例(必须)
256
281
  >>> def Raw_ob12(self, message, **kwargs):
257
282
  >>> return asyncio.create_task(
258
283
  >>> self._adapter.call_api(
@@ -265,20 +290,32 @@ class BaseAdapter:
265
290
  >>> )
266
291
  >>> )
267
292
  """
293
+
268
294
  async def _send_raw():
269
- from .. import logger
270
- logger.warning(f"适配器未实现 Raw_ob12 方法,原始消息未被发送: {message}")
271
- return None
272
-
295
+ from ..logger import logger
296
+
297
+ logger.error(
298
+ f"适配器 {self._adapter.__class__.__name__} 未实现 Raw_ob12 方法,"
299
+ f"消息未被发送。适配器必须实现此方法以支持 OneBot12 消息段发送。"
300
+ )
301
+ return {
302
+ "status": "failed",
303
+ "retcode": 10002,
304
+ "data": None,
305
+ "message_id": "",
306
+ "message": f"适配器 {self._adapter.__class__.__name__} 未实现 Raw_ob12 方法",
307
+ }
308
+
273
309
  return asyncio.create_task(_send_raw())
274
310
 
275
311
  def __init__(self):
276
312
  self.Send = self.__class__.Send(self)
277
313
 
314
+ @abstractmethod
278
315
  async def call_api(self, endpoint: str, **params: Any) -> Any:
279
316
  """
280
317
  调用平台API的抽象方法
281
-
318
+
282
319
  :param endpoint: API端点
283
320
  :param params: API参数
284
321
  :return: API调用结果
@@ -286,54 +323,65 @@ class BaseAdapter:
286
323
  """
287
324
  raise NotImplementedError("适配器必须实现call_api方法")
288
325
 
326
+ @abstractmethod
289
327
  async def start(self) -> None:
290
328
  """
291
329
  启动适配器的抽象方法
292
-
330
+
293
331
  :raises NotImplementedError: 必须由子类实现
294
332
  """
295
333
  raise NotImplementedError("适配器必须实现start方法")
296
-
334
+
335
+ @abstractmethod
297
336
  async def shutdown(self) -> None:
298
337
  """
299
338
  关闭适配器的抽象方法
300
-
339
+
301
340
  :raises NotImplementedError: 必须由子类实现
302
341
  """
303
342
  raise NotImplementedError("适配器必须实现shutdown方法")
304
-
343
+
305
344
  async def emit(self) -> None:
306
- from .. import logger
307
- logger.error("适配器调用了一个被弃用的原生方法emit,请检查适配器的实现,如果你是开发者请查看ErisPulse的文档进行更新。如果你是普通用户请查看本适配器是否有更新")
345
+ from ..logger import logger
308
346
 
309
- def send(self, target_type: str, target_id: str, message: Any, **kwargs: Any) -> asyncio.Task:
347
+ logger.error(
348
+ "适配器调用了一个被弃用的原生方法emit,请检查适配器的实现,如果你是开发者请查看ErisPulse的文档进行更新。如果你是普通用户请查看本适配器是否有更新"
349
+ )
350
+
351
+ def send(
352
+ self, target_type: str, target_id: str, message: Any, **kwargs: Any
353
+ ) -> asyncio.Task:
310
354
  """
311
355
  发送消息的便捷方法,返回一个 asyncio Task
312
-
356
+
313
357
  :param target_type: 目标类型
314
358
  :param target_id: 目标ID
315
359
  :param message: 消息内容
316
360
  :param kwargs: 其他参数
317
361
  - method: 发送方法名(默认为"Text")
318
362
  :return: asyncio.Task 对象,用户可以自主决定是否等待
319
-
363
+
320
364
  :raises AttributeError: 当发送方法不存在时抛出
321
-
365
+
322
366
  :example:
323
367
  >>> task = adapter.send("user", "123", "Hello")
324
368
  >>> # 用户可以选择等待: result = await task
325
369
  >>> # 或者不等待让其在后台执行
326
370
  >>> await adapter.send("group", "456", "Hello", method="Markdown") # 直接等待
327
371
  """
372
+
328
373
  async def _send_wrapper():
329
374
  method_name = kwargs.pop("method", "Text")
330
375
  method = getattr(self.Send.To(target_type, target_id), method_name, None)
331
376
  if not method:
332
- raise AttributeError(f"未找到 {method_name} 方法,请确保已在 Send 类中定义")
377
+ raise AttributeError(
378
+ f"未找到 {method_name} 方法,请确保已在 Send 类中定义"
379
+ )
333
380
  return await method(message, **kwargs)
334
-
381
+
335
382
  return asyncio.create_task(_send_wrapper())
336
383
 
384
+
337
385
  __all__ = [
338
386
  "BaseAdapter",
339
387
  "SendDSL",
@@ -16,7 +16,9 @@ ErisPulse 适配器基础模块
16
16
  """
17
17
 
18
18
  import asyncio
19
- from typing import Any, Optional, Union, Awaitable
19
+ from abc import ABC, abstractmethod
20
+ from typing import Any
21
+ from collections.abc import Awaitable
20
22
 
21
23
  class SendDSL:
22
24
  """
@@ -29,7 +31,7 @@ class SendDSL:
29
31
  2. 通过__getattr__实现动态方法调用
30
32
  {!--< /tips >!--}
31
33
  """
32
- def __init__(self: None, adapter: BaseAdapter, target_type: Optional[str] = ..., target_id: Optional[str] = ..., account_id: Optional[str] = ...) -> ...:
34
+ def __init__(self: None, adapter: BaseAdapter, target_type: str | None = ..., target_id: str | None = ..., account_id: str | None = ...) -> ...:
33
35
  """
34
36
  初始化DSL发送器
35
37
 
@@ -51,17 +53,27 @@ class SendDSL:
51
53
  :raises AttributeError: 当属性不存在时抛出
52
54
  """
53
55
  ...
56
+ def _unimplemented_modifier(self: object, method_name: str, **kwargs: ...) -> SendDSL:
57
+ """
58
+ 处理未实现的修饰方法,记录警告并返回自身以保持链式调用
59
+ """
60
+ ...
54
61
  def At(self: object, **kwargs: ...) -> ...:
55
62
  ...
56
63
  def Reply(self: object, **kwargs: ...) -> ...:
57
64
  ...
58
65
  def AtAll(self: object, **kwargs: ...) -> ...:
59
66
  ...
60
- def Raw_ob12(self: object, **kwargs: ...) -> ...:
61
- ...
62
- def Raw_json(self: object, **kwargs: ...) -> ...:
67
+ def Raw_ob12(self: object, message: ..., **kwargs: ...) -> ...:
68
+ """
69
+ 发送 OneBot12 格式消息段(必须由适配器子类重写)
70
+
71
+ :param message: OneBot12 消息段列表或单个消息段
72
+ :param kwargs: 其他参数
73
+ :return: asyncio.Task
74
+ """
63
75
  ...
64
- def To(self: object, target_type: str = ..., target_id: Union[(str, int)] = ...) -> SendDSL:
76
+ def To(self: object, target_type: str = ..., target_id: str | int = ...) -> SendDSL:
65
77
  """
66
78
  设置消息目标
67
79
 
@@ -82,7 +94,7 @@ class SendDSL:
82
94
  >>> adapter.Send.To("123").Text("Hello")
83
95
  """
84
96
  ...
85
- def Using(self: object, account_id: Union[(str, int)]) -> SendDSL:
97
+ def Using(self: object, account_id: str | int) -> SendDSL:
86
98
  """
87
99
  设置发送账号
88
100
 
@@ -94,7 +106,7 @@ class SendDSL:
94
106
  >>> adapter.Send.To("123").Using("bot1").Text("Hello") # 支持乱序
95
107
  """
96
108
  ...
97
- def Account(self: object, account_id: Union[(str, int)]) -> SendDSL:
109
+ def Account(self: object, account_id: str | int) -> SendDSL:
98
110
  """
99
111
  设置发送账号
100
112
 
@@ -107,7 +119,7 @@ class SendDSL:
107
119
  """
108
120
  ...
109
121
 
110
- class BaseAdapter:
122
+ class BaseAdapter(ABC):
111
123
  """
112
124
  适配器基类
113
125
 
@@ -160,7 +172,7 @@ class BaseAdapter:
160
172
  :return: asyncio.Task 对象,用户可以自主决定是否等待
161
173
 
162
174
  :raises AttributeError: 当发送方法不存在时抛出
163
-
175
+
164
176
  :example:
165
177
  >>> task = adapter.send("user", "123", "Hello")
166
178
  >>> # 用户可以选择等待: result = await task