Source code for duetector.managers.analyzer

from __future__ import annotations

import sys
from typing import Any

import pluggy

import duetector.analyzer.register
from duetector.analyzer.base import Analyzer
from duetector.extension.analyzer import project_name
from duetector.log import logger
from duetector.managers.base import Manager

PROJECT_NAME = project_name  #: Default project name for pluggy
hookspec = pluggy.HookspecMarker(PROJECT_NAME)


[docs] @hookspec def init_analyzer(config) -> Analyzer | None: """ Initialize analyzer from config None means the analyzer is not available Also the analyzer can be disabled by config, Manager will discard disabled analyzer """
[docs] class AnalyzerManager(Manager): """ Manager for all analyzers. Analyzers are initialized from config, and can be ``disabled`` by config. """ config_scope = "analyzer" """ Config scope for ``AnalyzerManager``. """ def __init__(self, config: dict[str, Any] = None, *args, **kwargs): super().__init__(config, *args, **kwargs) self.pm = pluggy.PluginManager(PROJECT_NAME) self.pm.add_hookspecs(sys.modules[__name__]) if self.include_extension: self.pm.load_setuptools_entrypoints(PROJECT_NAME) self.register(duetector.analyzer.register)
[docs] def init(self, analyzer_type=Analyzer, ignore_disabled=True, *args, **kwargs) -> list[Analyzer]: """ Initialize all analyzers from config. Args: analyzer_type: Only return analyzers of this type ignore_disabled: Ignore disabled analyzers """ if self.disabled: logger.info("AnalyzerManager disabled.") return [] objs = [] for f in self.pm.hook.init_analyzer(config=self.config._config_dict): if not f or (f.disabled and ignore_disabled): logger.debug(f"Analyzer {f.__class__.__name__} is not available (None or Disabled)") continue if not isinstance(f, analyzer_type): logger.debug( f"Skip Analyzer {f.__class__.__name__} (Not a instance of {analyzer_type})" ) continue objs.append(f) return objs