Coverage for src/symphra_modules/loader/package.py: 93.55%
25 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-26 18:16 +0800
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-26 18:16 +0800
1"""包加载器实现."""
3import importlib
4from pathlib import Path
6from symphra_modules.abc import ModuleInterface
7from symphra_modules.exceptions import ModuleLoadError
8from symphra_modules.loader.base import ModuleLoader
11class PackageLoader(ModuleLoader):
12 """从包名加载模块."""
14 def load(self, source: str) -> dict[str, type[ModuleInterface]]:
15 """从包名加载模块.
17 Args:
18 source: 包名(如 "my_package.modules")
20 Returns:
21 模块类字典
23 Raises:
24 ModuleLoadError: 包未找到时抛出
25 """
26 try:
27 module = importlib.import_module(source)
28 return self._find_module_classes(module)
29 except ImportError as e:
30 raise ModuleLoadError(f"包未找到: {source}") from e
32 def discover(self, source: str) -> list[str]:
33 """发现包中的模块.
35 Args:
36 source: 包名
38 Returns:
39 模块名称列表
40 """
41 try:
42 package = importlib.import_module(source)
43 package_path = Path(package.__file__).parent if package.__file__ else Path.cwd() / source
45 module_names: list[str] = []
47 # 扫描包内的模块
48 for item in package_path.iterdir():
49 if item.is_file() and item.suffix == ".py" and not item.name.startswith("_"):
50 module_names.append(item.stem)
51 elif item.is_dir() and (item / "__init__.py").exists(): 51 ↛ 52line 51 didn't jump to line 52 because the condition on line 51 was never true
52 module_names.append(item.name)
54 return module_names
56 except (ImportError, AttributeError):
57 return []