"""Utilities shared by benchmark evaluators.""" from __future__ import annotations import importlib import logging import re from typing import Dict, Iterable, List logger = logging.getLogger(__name__) def _guess_dataset_var(mod_path: str) -> str: """Guess the dataset variable name from an OpenCompass module path. Convention: ``opencompass.configs.datasets.._gen_`` exports ``_datasets``. E.g.: - ``bbh.bbh_gen_ee62e9`` → ``bbh_datasets`` - ``gsm8k.gsm8k_gen_1d7fe4`` → ``gsm8k_datasets`` - ``ARC_c.ARC_c_gen_1e0de5`` → ``ARC_c_datasets`` """ # Take the parent package name (e.g. "bbh" from "...datasets.bbh.bbh_gen_xxx") parts = mod_path.rsplit(".", 2) if len(parts) >= 2: parent = parts[-2] # e.g. "bbh", "gsm8k", "ARC_c" return f"{parent}_datasets" return "datasets" def build_dataset_imports_explicit(dataset_imports: str | Iterable[str]) -> List[Dict[str, object]]: """Build explicit dataset import specs for the OpenCompass config template. Resolve explicit dataset variable names to avoid `import *`, which leaks non-serializable objects (e.g. `os`, `f` from BBH) and breaks mmengine's config dump+reload in the CLI. The returned structure matches `opencompass_template.yaml` expectation: `[{ "module": "...", "names": ["datasets", "..._datasets"] }, ...]`. """ modules = [dataset_imports] if isinstance(dataset_imports, str) else list(dataset_imports) explicit: List[Dict[str, object]] = [] for mod_path in modules: try: mod = importlib.import_module(mod_path) names = [ attr for attr in dir(mod) if (attr == "datasets" or attr.endswith("_datasets")) and isinstance(getattr(mod, attr), list) ] if not names: guessed = _guess_dataset_var(mod_path) logger.warning( "No dataset variables found in %s, guessing '%s'", mod_path, guessed, ) names = [guessed] explicit.append({"module": mod_path, "names": names}) except Exception as e: guessed = _guess_dataset_var(mod_path) logger.warning( "Failed to import %s for explicit name resolution: %s. " "Guessing variable name '%s'.", mod_path, e, guessed, ) explicit.append({"module": mod_path, "names": [guessed]}) return explicit