Coverage for /home/benjarobin/Bootlin/projects/Schneider-Electric-Senux/sbom-cve-check/src/sbom_cve_check/utils/plugin.py: 66%

41 statements  

« prev     ^ index     » next       coverage.py v7.11.1, created at 2025-11-28 15:37 +0100

1# -*- coding: utf-8 -*- 

2# SPDX-License-Identifier: GPL-2.0-only 

3 

4import importlib 

5import importlib.machinery 

6import importlib.util 

7import logging 

8import pathlib 

9import pkgutil 

10import sys 

11 

12_logger = logging.getLogger(__name__) 

13 

14 

15def import_builtin_plugin(pkg: str, mod: str) -> None: 

16 try: 

17 importlib.import_module(mod, pkg) 

18 except ImportError as e: 

19 _logger.debug("Fail to load %s%s builtin plugin: %s", pkg, mod, str(e)) 

20 

21 

22def _load_plugin(spec: importlib.machinery.ModuleSpec | None, pkg_name: str) -> None: 

23 if spec is not None: 

24 plugin = importlib.util.module_from_spec(spec) 

25 if plugin is not None: 

26 sys.modules[pkg_name] = plugin 

27 if spec.loader is not None: 

28 try: 

29 spec.loader.exec_module(plugin) 

30 except ImportError as e: 

31 _logger.debug( 

32 "Fail to load %s builtin plugin: %s", pkg_name, str(e) 

33 ) 

34 

35 

36def import_external_plugin(search_path: set[pathlib.Path]) -> None: 

37 plugin_namespace = f"{__package__}.plugins" 

38 if sys.modules.get(plugin_namespace) is None: 

39 ns_spec = importlib.machinery.ModuleSpec( 

40 plugin_namespace, None, is_package=True 

41 ) 

42 _load_plugin(ns_spec, plugin_namespace) 

43 

44 for search_pkg in [ 

45 p for p in search_path if (p.is_dir() and p.joinpath("__init__.py").is_file()) 

46 ]: 

47 search_path.remove(search_pkg) 

48 finder_pkg = pkgutil.get_importer(str(search_pkg.parent)) 

49 if finder_pkg is not None: 

50 pkg_name = f"{plugin_namespace}.{search_pkg.name}" 

51 _load_plugin(finder_pkg.find_spec(pkg_name), pkg_name) 

52 

53 for search_file in [p for p in search_path if (p.is_file() and p.suffix != ".zip")]: 

54 search_path.remove(search_file) 

55 pkg_name = f"{plugin_namespace}.{search_file.stem}" 

56 _load_plugin( 

57 importlib.util.spec_from_file_location(pkg_name, search_file), pkg_name 

58 ) 

59 

60 # noinspection PyTypeChecker 

61 for finder, name, _ in pkgutil.iter_modules(search_path): 

62 pkg_name = f"{plugin_namespace}.{name}" 

63 _load_plugin(finder.find_spec(pkg_name), pkg_name) # type: ignore[call-arg]