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

1"""包加载器实现.""" 

2 

3import importlib 

4from pathlib import Path 

5 

6from symphra_modules.abc import ModuleInterface 

7from symphra_modules.exceptions import ModuleLoadError 

8from symphra_modules.loader.base import ModuleLoader 

9 

10 

11class PackageLoader(ModuleLoader): 

12 """从包名加载模块.""" 

13 

14 def load(self, source: str) -> dict[str, type[ModuleInterface]]: 

15 """从包名加载模块. 

16 

17 Args: 

18 source: 包名(如 "my_package.modules") 

19 

20 Returns: 

21 模块类字典 

22 

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 

31 

32 def discover(self, source: str) -> list[str]: 

33 """发现包中的模块. 

34 

35 Args: 

36 source: 包名 

37 

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 

44 

45 module_names: list[str] = [] 

46 

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) 

53 

54 return module_names 

55 

56 except (ImportError, AttributeError): 

57 return []