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.
Files changed (97) hide show
  1. ErisPulse/CLI/__init__.py +11 -0
  2. ErisPulse/CLI/__init__.pyi +13 -0
  3. ErisPulse/CLI/base.py +52 -0
  4. ErisPulse/CLI/base.pyi +50 -0
  5. ErisPulse/CLI/cli.py +224 -0
  6. ErisPulse/CLI/cli.pyi +80 -0
  7. ErisPulse/CLI/commands/__init__.py +6 -0
  8. ErisPulse/CLI/commands/__init__.pyi +12 -0
  9. ErisPulse/CLI/commands/init.py +395 -0
  10. ErisPulse/CLI/commands/init.pyi +70 -0
  11. ErisPulse/CLI/commands/install.py +302 -0
  12. ErisPulse/CLI/commands/install.pyi +58 -0
  13. ErisPulse/CLI/commands/list.py +160 -0
  14. ErisPulse/CLI/commands/list.pyi +44 -0
  15. ErisPulse/CLI/commands/list_remote.py +123 -0
  16. ErisPulse/CLI/commands/list_remote.pyi +35 -0
  17. ErisPulse/CLI/commands/run.py +108 -0
  18. ErisPulse/CLI/commands/run.pyi +39 -0
  19. ErisPulse/CLI/commands/self_update.py +232 -0
  20. ErisPulse/CLI/commands/self_update.pyi +47 -0
  21. ErisPulse/CLI/commands/uninstall.py +32 -0
  22. ErisPulse/CLI/commands/uninstall.pyi +24 -0
  23. ErisPulse/CLI/commands/upgrade.py +56 -0
  24. ErisPulse/CLI/commands/upgrade.pyi +25 -0
  25. ErisPulse/CLI/console.pyi +20 -0
  26. ErisPulse/CLI/registry.py +112 -0
  27. ErisPulse/CLI/registry.pyi +99 -0
  28. ErisPulse/{utils → CLI/utils}/__init__.py +2 -6
  29. ErisPulse/CLI/utils/__init__.pyi +14 -0
  30. ErisPulse/{utils → CLI/utils}/package_manager.py +146 -20
  31. ErisPulse/CLI/utils/package_manager.pyi +241 -0
  32. ErisPulse/{utils → CLI/utils}/reload_handler.py +7 -8
  33. ErisPulse/CLI/utils/reload_handler.pyi +64 -0
  34. ErisPulse/Core/Bases/__init__.pyi +14 -0
  35. ErisPulse/Core/Bases/adapter.py +13 -1
  36. ErisPulse/Core/Bases/adapter.pyi +140 -0
  37. ErisPulse/Core/Bases/manager.py +136 -0
  38. ErisPulse/Core/Bases/manager.pyi +108 -0
  39. ErisPulse/Core/Bases/module.py +53 -1
  40. ErisPulse/Core/Bases/module.pyi +95 -0
  41. ErisPulse/Core/Event/__init__.pyi +26 -0
  42. ErisPulse/Core/Event/base.pyi +62 -0
  43. ErisPulse/Core/Event/command.py +6 -1
  44. ErisPulse/Core/Event/command.pyi +113 -0
  45. ErisPulse/Core/Event/exceptions.pyi +43 -0
  46. ErisPulse/Core/Event/message.pyi +93 -0
  47. ErisPulse/Core/Event/meta.pyi +92 -0
  48. ErisPulse/Core/Event/notice.pyi +108 -0
  49. ErisPulse/Core/Event/request.pyi +76 -0
  50. ErisPulse/Core/Event/wrapper.py +2 -3
  51. ErisPulse/Core/Event/wrapper.pyi +403 -0
  52. ErisPulse/Core/__init__.py +16 -13
  53. ErisPulse/Core/__init__.pyi +16 -0
  54. ErisPulse/Core/_self_config.py +1 -1
  55. ErisPulse/Core/_self_config.pyi +72 -0
  56. ErisPulse/Core/adapter.py +70 -10
  57. ErisPulse/Core/adapter.pyi +246 -0
  58. ErisPulse/Core/config.pyi +70 -0
  59. ErisPulse/Core/exceptions.py +4 -2
  60. ErisPulse/Core/exceptions.pyi +60 -0
  61. ErisPulse/Core/lifecycle.py +15 -1
  62. ErisPulse/Core/lifecycle.pyi +92 -0
  63. ErisPulse/Core/logger.py +21 -15
  64. ErisPulse/Core/logger.pyi +169 -0
  65. ErisPulse/Core/module.py +57 -9
  66. ErisPulse/Core/module.pyi +189 -0
  67. ErisPulse/Core/router.py +13 -5
  68. ErisPulse/Core/router.pyi +120 -0
  69. ErisPulse/Core/storage.py +94 -256
  70. ErisPulse/Core/storage.pyi +220 -0
  71. ErisPulse/__init__.py +35 -1236
  72. ErisPulse/__init__.pyi +22 -0
  73. ErisPulse/__main__.py +1 -1
  74. ErisPulse/__main__.pyi +24 -0
  75. ErisPulse/loaders/__init__.py +22 -0
  76. ErisPulse/loaders/__init__.pyi +21 -0
  77. ErisPulse/loaders/adapter_loader.py +187 -0
  78. ErisPulse/loaders/adapter_loader.pyi +82 -0
  79. ErisPulse/loaders/base_loader.py +162 -0
  80. ErisPulse/loaders/base_loader.pyi +23 -0
  81. ErisPulse/loaders/initializer.py +150 -0
  82. ErisPulse/loaders/initializer.pyi +60 -0
  83. ErisPulse/loaders/module_loader.py +618 -0
  84. ErisPulse/loaders/module_loader.pyi +179 -0
  85. ErisPulse/loaders/strategy.py +129 -0
  86. ErisPulse/loaders/strategy.pyi +90 -0
  87. ErisPulse/sdk.py +435 -0
  88. ErisPulse/sdk.pyi +158 -0
  89. {erispulse-2.3.3.dev0.dist-info → erispulse-2.3.4.dev2.dist-info}/METADATA +6 -20
  90. erispulse-2.3.4.dev2.dist-info/RECORD +103 -0
  91. {erispulse-2.3.3.dev0.dist-info → erispulse-2.3.4.dev2.dist-info}/licenses/LICENSE +3 -3
  92. ErisPulse/Core/ux.py +0 -635
  93. ErisPulse/utils/cli.py +0 -1097
  94. erispulse-2.3.3.dev0.dist-info/RECORD +0 -35
  95. /ErisPulse/{utils → CLI}/console.py +0 -0
  96. {erispulse-2.3.3.dev0.dist-info → erispulse-2.3.4.dev2.dist-info}/WHEEL +0 -0
  97. {erispulse-2.3.3.dev0.dist-info → erispulse-2.3.4.dev2.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,112 @@
1
+ """
2
+ CLI 命令注册器
3
+
4
+ 负责命令的注册、查找和管理
5
+ """
6
+
7
+ from typing import Optional, List, Dict
8
+ from .base import Command
9
+
10
+
11
+ class CommandRegistry:
12
+ """
13
+ 命令注册器
14
+
15
+ 管理所有已注册的 CLI 命令
16
+
17
+ {!--< tips >!--}
18
+ 1. 使用单例模式确保全局唯一
19
+ 2. 支持命令的动态注册和查找
20
+ 3. 支持第三方命令的兼容
21
+ {!--< /tips >!--}
22
+
23
+ :ivar _commands: 已注册的命令字典 {name: Command}
24
+ """
25
+
26
+ _instance = None
27
+
28
+ def __new__(cls):
29
+ """实现单例模式"""
30
+ if cls._instance is None:
31
+ cls._instance = super().__new__(cls)
32
+ cls._instance._commands: Dict[str, Command] = {}
33
+ cls._instance._external_commands: Dict[str, Command] = {}
34
+ return cls._instance
35
+
36
+ def register(self, command: Command):
37
+ """
38
+ 注册命令
39
+
40
+ :param command: 要注册的命令实例
41
+ :raises ValueError: 命令名称已存在时抛出
42
+ """
43
+ if command.name in self._commands:
44
+ raise ValueError(f"命令 '{command.name}' 已存在")
45
+ self._commands[command.name] = command
46
+
47
+ def register_external(self, name: str, command: Command):
48
+ """
49
+ 注册第三方命令
50
+
51
+ :param name: 命令名称
52
+ :param command: 命令实例
53
+ """
54
+ self._external_commands[name] = command
55
+
56
+ def get(self, name: str) -> Optional[Command]:
57
+ """
58
+ 获取命令
59
+
60
+ :param name: 命令名称
61
+ :return: 命令实例,未找到返回 None
62
+ """
63
+ # 优先查找内置命令
64
+ if name in self._commands:
65
+ return self._commands[name]
66
+ # 然后查找外部命令
67
+ return self._external_commands.get(name)
68
+
69
+ def get_all(self) -> List[Command]:
70
+ """
71
+ 获取所有命令(包括外部命令)
72
+
73
+ :return: 所有命令列表
74
+ """
75
+ return list(self._commands.values()) + list(self._external_commands.values())
76
+
77
+ def list_all(self) -> List[str]:
78
+ """
79
+ 列出所有命令名称
80
+
81
+ :return: 命令名称列表
82
+ """
83
+ return list(self._commands.keys()) + list(self._external_commands.keys())
84
+
85
+ def list_builtin(self) -> List[str]:
86
+ """
87
+ 列出内置命令名称
88
+
89
+ :return: 内置命令名称列表
90
+ """
91
+ return list(self._commands.keys())
92
+
93
+ def list_external(self) -> List[str]:
94
+ """
95
+ 列出外部命令名称
96
+
97
+ :return: 外部命令名称列表
98
+ """
99
+ return list(self._external_commands.keys())
100
+
101
+ def exists(self, name: str) -> bool:
102
+ """
103
+ 检查命令是否存在
104
+
105
+ :param name: 命令名称
106
+ :return: 命令是否存在
107
+ """
108
+ return name in self._commands or name in self._external_commands
109
+
110
+ def clear_external(self):
111
+ """清空外部命令"""
112
+ self._external_commands.clear()
@@ -0,0 +1,99 @@
1
+ # type: ignore
2
+ #
3
+ # Auto-generated type stub for registry.py
4
+ # DO NOT EDIT MANUALLY - Generated by generate-type-stubs.py
5
+ #
6
+
7
+ """
8
+ CLI 命令注册器
9
+
10
+ 负责命令的注册、查找和管理
11
+ """
12
+
13
+ from typing import Optional, List, Dict
14
+ from .base import Command
15
+
16
+ class CommandRegistry:
17
+ """
18
+ 命令注册器
19
+
20
+ 管理所有已注册的 CLI 命令
21
+
22
+ {!--< tips >!--}
23
+ 1. 使用单例模式确保全局唯一
24
+ 2. 支持命令的动态注册和查找
25
+ 3. 支持第三方命令的兼容
26
+ {!--< /tips >!--}
27
+
28
+ :ivar _commands: 已注册的命令字典 {name: Command}
29
+ """
30
+ def __new__(cls: object) -> ...:
31
+ """
32
+ 实现单例模式
33
+ """
34
+ ...
35
+ def register(self: object, command: Command) -> ...:
36
+ """
37
+ 注册命令
38
+
39
+ :param command: 要注册的命令实例
40
+ :raises ValueError: 命令名称已存在时抛出
41
+ """
42
+ ...
43
+ def register_external(self: object, name: str, command: Command) -> ...:
44
+ """
45
+ 注册第三方命令
46
+
47
+ :param name: 命令名称
48
+ :param command: 命令实例
49
+ """
50
+ ...
51
+ def get(self: object, name: str) -> Optional[Command]:
52
+ """
53
+ 获取命令
54
+
55
+ :param name: 命令名称
56
+ :return: 命令实例,未找到返回 None
57
+ """
58
+ ...
59
+ def get_all(self: object) -> List[Command]:
60
+ """
61
+ 获取所有命令(包括外部命令)
62
+
63
+ :return: 所有命令列表
64
+ """
65
+ ...
66
+ def list_all(self: object) -> List[str]:
67
+ """
68
+ 列出所有命令名称
69
+
70
+ :return: 命令名称列表
71
+ """
72
+ ...
73
+ def list_builtin(self: object) -> List[str]:
74
+ """
75
+ 列出内置命令名称
76
+
77
+ :return: 内置命令名称列表
78
+ """
79
+ ...
80
+ def list_external(self: object) -> List[str]:
81
+ """
82
+ 列出外部命令名称
83
+
84
+ :return: 外部命令名称列表
85
+ """
86
+ ...
87
+ def exists(self: object, name: str) -> bool:
88
+ """
89
+ 检查命令是否存在
90
+
91
+ :param name: 命令名称
92
+ :return: 命令是否存在
93
+ """
94
+ ...
95
+ def clear_external(self: object) -> ...:
96
+ """
97
+ 清空外部命令
98
+ """
99
+ ...
@@ -6,12 +6,8 @@ ErisPulse SDK 工具模块
6
6
 
7
7
  from .package_manager import PackageManager
8
8
  from .reload_handler import ReloadHandler
9
- from .cli import CLI
10
- from .console import console
11
9
 
12
10
  __all__ = [
13
11
  "PackageManager",
14
- "ReloadHandler",
15
- "CLI",
16
- "console",
17
- ]
12
+ "ReloadHandler"
13
+ ]
@@ -0,0 +1,14 @@
1
+ # type: ignore
2
+ #
3
+ # Auto-generated type stub for __init__.py
4
+ # DO NOT EDIT MANUALLY - Generated by generate-type-stubs.py
5
+ #
6
+
7
+ """
8
+ ErisPulse SDK 工具模块
9
+
10
+ 包含各种辅助工具和实用程序。
11
+ """
12
+
13
+ from .package_manager import PackageManager
14
+ from .reload_handler import ReloadHandler
@@ -17,7 +17,7 @@ from rich.panel import Panel
17
17
  from rich.progress import Progress, BarColumn, TextColumn
18
18
  from rich.prompt import Confirm
19
19
 
20
- from .console import console
20
+ from ..console import console
21
21
 
22
22
  class PackageManager:
23
23
  """
@@ -41,6 +41,8 @@ class PackageManager:
41
41
  """初始化包管理器"""
42
42
  self._cache = {}
43
43
  self._cache_time = {}
44
+ self._pypi_cache = {} # PyPI版本缓存
45
+ self._pypi_cache_time = {} # PyPI版本缓存时间
44
46
 
45
47
  async def _fetch_remote_packages(self, url: str) -> Optional[dict]:
46
48
  """
@@ -204,27 +206,42 @@ class PackageManager:
204
206
  async def _find_package_by_alias(self, alias: str) -> Optional[str]:
205
207
  """
206
208
  通过别名查找实际包名(大小写不敏感)
209
+ 支持查找已安装包和远程包
207
210
 
208
- :param alias: 包别名
211
+ :param alias: 包别名或PyPI包名
209
212
  :return: 实际包名,未找到返回None
210
213
  """
211
214
  normalized_alias = self._normalize_name(alias)
212
215
  remote_packages = await self.get_remote_packages()
213
216
 
217
+ # 首先检查是否是已安装包的PyPI包名
218
+ installed_package = self._find_installed_package_by_name(alias)
219
+ if installed_package:
220
+ return installed_package
221
+
214
222
  # 检查模块
215
223
  for name, info in remote_packages["modules"].items():
216
224
  if self._normalize_name(name) == normalized_alias:
217
225
  return info["package"]
226
+ # 同时检查PyPI包名
227
+ if self._normalize_name(info["package"]) == normalized_alias:
228
+ return info["package"]
218
229
 
219
230
  # 检查适配器
220
231
  for name, info in remote_packages["adapters"].items():
221
232
  if self._normalize_name(name) == normalized_alias:
222
233
  return info["package"]
234
+ # 同时检查PyPI包名
235
+ if self._normalize_name(info["package"]) == normalized_alias:
236
+ return info["package"]
223
237
 
224
238
  # 检查CLI扩展
225
239
  for name, info in remote_packages.get("cli_extensions", {}).items():
226
240
  if self._normalize_name(name) == normalized_alias:
227
241
  return info["package"]
242
+ # 同时检查PyPI包名
243
+ if self._normalize_name(info["package"]) == normalized_alias:
244
+ return info["package"]
228
245
 
229
246
  return None
230
247
 
@@ -255,6 +272,80 @@ class PackageManager:
255
272
 
256
273
  return None
257
274
 
275
+ async def check_package_updates(self) -> Dict[str, Tuple[str, str]]:
276
+ """
277
+ 检查包更新,对比本地版本和远程版本
278
+
279
+ :return: {包名: (当前版本, 最新版本)},仅包含有新版本的包
280
+ """
281
+ installed = self.get_installed_packages()
282
+ remote_packages = await self.get_remote_packages()
283
+
284
+ updates = {}
285
+
286
+ # 构建远程包索引:PyPI包名 -> 版本
287
+ remote_index = {}
288
+ for pkg_type in ["modules", "adapters", "cli_extensions"]:
289
+ for name, info in remote_packages[pkg_type].items():
290
+ remote_index[info["package"]] = info["version"]
291
+
292
+ # 检查每个已安装包
293
+ for pkg_type in ["modules", "adapters", "cli_extensions"]:
294
+ for entry_name, pkg_info in installed[pkg_type].items():
295
+ current_version = pkg_info["version"]
296
+ package_name = pkg_info["package"]
297
+
298
+ # 检查远程是否有更新
299
+ if package_name in remote_index:
300
+ remote_version = remote_index[package_name]
301
+
302
+ # 比较版本
303
+ comparison = self._compare_versions(remote_version, current_version)
304
+ if comparison > 0: # 远程版本更新
305
+ updates[package_name] = (current_version, remote_version)
306
+ else:
307
+ # 如果远程找不到,尝试通过PyPI检查(使用pip show)
308
+ remote_version = await self._get_pypi_package_version(package_name)
309
+ if remote_version and self._compare_versions(remote_version, current_version) > 0:
310
+ updates[package_name] = (current_version, remote_version)
311
+
312
+ return updates
313
+
314
+ async def _get_pypi_package_version(self, package_name: str, force_refresh: bool = False) -> Optional[str]:
315
+ """
316
+ 从PyPI获取包的最新版本,带缓存机制
317
+
318
+ :param package_name: PyPI包名
319
+ :param force_refresh: 是否强制刷新缓存
320
+ :return: 最新版本号,失败返回None
321
+ """
322
+ # 检查缓存
323
+ cache_key = package_name.lower()
324
+ if not force_refresh and cache_key in self._pypi_cache:
325
+ if time.time() - self._pypi_cache_time[cache_key] < self.CACHE_EXPIRY:
326
+ return self._pypi_cache[cache_key]
327
+
328
+ import aiohttp
329
+ from aiohttp import ClientError, ClientTimeout
330
+
331
+ timeout = ClientTimeout(total=10)
332
+ url = f"https://pypi.org/pypi/{package_name}/json"
333
+
334
+ try:
335
+ async with aiohttp.ClientSession(timeout=timeout) as session:
336
+ async with session.get(url) as response:
337
+ if response.status == 200:
338
+ data = await response.json()
339
+ version = data["info"]["version"]
340
+ # 更新缓存
341
+ self._pypi_cache[cache_key] = version
342
+ self._pypi_cache_time[cache_key] = time.time()
343
+ return version
344
+ except (ClientError, asyncio.TimeoutError, json.JSONDecodeError, KeyError) as e:
345
+ console.print(f"[warning]获取PyPI版本失败 ({package_name}): {e}[/]")
346
+
347
+ return None
348
+
258
349
  def _run_pip_command_with_output(self, args: List[str], description: str) -> Tuple[bool, str, str]:
259
350
  """
260
351
  执行pip命令并捕获输出
@@ -537,35 +628,42 @@ class PackageManager:
537
628
 
538
629
  def upgrade_all(self) -> bool:
539
630
  """
540
- 升级所有已安装的ErisPulse包
631
+ 升级所有有新版本的ErisPulse包
541
632
 
542
633
  :return: 升级是否成功
543
634
 
544
635
  :raises KeyboardInterrupt: 用户取消操作时抛出
545
636
  """
546
- installed = self.get_installed_packages()
547
- all_packages = set()
637
+ # 检查可更新的包
638
+ updates = asyncio.run(self.check_package_updates())
548
639
 
549
- for pkg_type in ["modules", "adapters", "cli_extensions"]:
550
- for pkg_info in installed[pkg_type].values():
551
- all_packages.add(pkg_info["package"])
640
+ if not updates:
641
+ console.print("[success]所有ErisPulse包已是最新版本[/]")
642
+ return True
552
643
 
553
- if not all_packages:
554
- console.print("[info]没有找到可升级的ErisPulse包[/]")
555
- return False
556
-
644
+ # 显示可升级的包列表
557
645
  console.print(Panel(
558
- f"找到 [bold]{len(all_packages)}[/] 个可升级的包:\n" +
559
- "\n".join(f" - [package]{pkg}[/]" for pkg in sorted(all_packages)),
646
+ f"找到 [bold]{len(updates)}[/] 个可升级的包:\n" +
647
+ "\n".join(
648
+ f" - [package]{pkg}[/] [dim]{current_ver}[/] → [success]{new_ver}[/]"
649
+ for pkg, (current_ver, new_ver) in updates.items()
650
+ ),
560
651
  title="升级列表"
561
652
  ))
562
653
 
563
- if not Confirm.ask("确认升级所有包吗?", default=False):
654
+ if not Confirm.ask("确认升级以上包吗?", default=False):
655
+ console.print("[info]操作已取消[/]")
564
656
  return False
565
-
657
+
658
+ # 执行升级
566
659
  results = {}
567
- for pkg in sorted(all_packages):
660
+ for pkg in sorted(updates.keys()):
661
+ console.print(f"\n[info]正在升级 [package]{pkg}[/]...")
568
662
  results[pkg] = self.install_package([pkg], upgrade=True)
663
+
664
+ # 显示结果摘要
665
+ success_count = sum(1 for success in results.values() if success)
666
+ console.print(f"\n[success]升级完成: {success_count}/{len(results)} 个包成功[/]")
569
667
 
570
668
  failed = [pkg for pkg, success in results.items() if not success]
571
669
  if failed:
@@ -593,13 +691,41 @@ class PackageManager:
593
691
  actual_package = asyncio.run(self._find_package_by_alias(package_name))
594
692
 
595
693
  if actual_package:
596
- console.print(f"[info]找到别名映射: [bold]{package_name}[/] → [package]{actual_package}[/][/]")
694
+ console.print(f"[info]找到包: [package]{actual_package}[/][/]")
597
695
  current_package_name = actual_package
598
696
  else:
599
697
  current_package_name = package_name
600
698
 
699
+ # 检查当前版本和远程版本
700
+ installed = self.get_installed_packages()
701
+ current_version = None
702
+ for pkg_type in ["modules", "adapters", "cli_extensions"]:
703
+ for pkg_info in installed[pkg_type].values():
704
+ if pkg_info["package"] == current_package_name:
705
+ current_version = pkg_info["version"]
706
+ break
707
+ if current_version:
708
+ break
709
+
710
+ # 获取远程版本
711
+ remote_version = asyncio.run(self._get_pypi_package_version(current_package_name))
712
+
713
+ # 显示版本信息
714
+ if current_version:
715
+ if remote_version:
716
+ comparison = self._compare_versions(remote_version, current_version)
717
+ if comparison <= 0:
718
+ console.print(f"[success]{current_package_name} 已是最新版本 ({current_version})[/]")
719
+ continue
720
+ else:
721
+ console.print(f"[info]{current_package_name}: {current_version} → {remote_version}[/]")
722
+ else:
723
+ console.print(f"[info]{current_package_name}: 当前版本 {current_version}[/]")
724
+ else:
725
+ console.print(f"[warning]未找到 {current_package_name} 的安装信息[/]")
726
+
601
727
  # 检查SDK版本兼容性
602
- package_info = asyncio.run(self._get_package_info(package_name))
728
+ package_info = asyncio.run(self._get_package_info(current_package_name))
603
729
  if package_info and "min_sdk_version" in package_info:
604
730
  is_compatible, message = self._check_sdk_compatibility(package_info["min_sdk_version"])
605
731
  if not is_compatible:
@@ -842,4 +968,4 @@ except:
842
968
  border_style="error"
843
969
  ))
844
970
 
845
- return success
971
+ return success