"""Registry that auto-discovers mutation rules from the rules directory.""" import importlib import inspect from pathlib import Path from typing import Dict, List, Type from app.dataset.rules.base import MutationRule class RuleRegistry: def __init__(self, rules_dir: Path): self.rules_dir = rules_dir self._rules: Dict[str, List[MutationRule]] = {} def discover(self) -> None: """Scan rules directory and register all MutationRule subclasses.""" self._rules.clear() for lang_dir in self.rules_dir.iterdir(): if not lang_dir.is_dir(): continue for py_file in lang_dir.glob("*.py"): if py_file.name.startswith("_"): continue module_name = f"app.dataset.rules.{lang_dir.name}.{py_file.stem}" try: module = importlib.import_module(module_name) except Exception: continue for _, obj in inspect.getmembers(module, inspect.isclass): if ( issubclass(obj, MutationRule) and obj is not MutationRule and not getattr(obj, "__abstractmethods__", False) ): rule = obj() self._rules.setdefault(rule.language, []).append(rule) def rules_for(self, language: str) -> List[MutationRule]: return self._rules.get(language, []) def all_rules(self) -> Dict[str, List[MutationRule]]: return self._rules.copy() def get_registry() -> RuleRegistry: registry = RuleRegistry(Path(__file__).parent) registry.discover() return registry