Source code for eval_framework.subjects

"""Subjects: the slices a benchmark's evaluation partitions into — which dataset config each loads,
and how each is labelled in samples, metadata, and result aggregation.

A ``SubjectsSelector`` turns the ``--task-subjects`` selector tokens a run requests into the concrete
``Subjects`` to evaluate (an empty token list means "all")."""

from abc import ABC, abstractmethod
from collections.abc import Sequence
from dataclasses import dataclass
from typing import final, override


[docs] @dataclass(frozen=True) class Subject: """One evaluation slice. ``load_key`` selects the dataset config to load (``None`` means the dataset's single config); ``label`` identifies the slice in samples, metadata, and result aggregation. """ load_key: str | None label: str
Subjects = Sequence[Subject]
[docs] class SubjectsSelector(ABC): """Selects which slices a run evaluates from its ``--task-subjects`` tokens; ``[]`` selects all."""
[docs] @abstractmethod def select(self, tokens: list[str]) -> Subjects: ...
[docs] @final class NoSubject(SubjectsSelector): """A task with no subjects: a single unnamed slice. Any selector other than ``"*"`` is an error."""
[docs] @override def select(self, tokens: list[str]) -> Subjects: if tokens and tokens != ["*"]: raise ValueError("This task has no subjects; drop --task-subjects (or pass '*').") return (Subject(load_key=None, label="no_subject"),)
[docs] @final class ListOfSubjects(SubjectsSelector): """A task whose subjects are named dataset configs. Each name is both the config to load and the slice's label; a selector picks names exactly, or ``"*"`` picks all.""" def __init__(self, names: list[str]) -> None: self._names = names
[docs] @override def select(self, tokens: list[str]) -> Subjects: if tokens: unknown = [token for token in tokens if token != "*" and token not in self._names] if unknown: raise ValueError(f"Unknown subject(s) {unknown}; this task's subjects are {self._names}.") wildcard = "*" in tokens names = [name for name in self._names if wildcard or name in tokens] else: names = self._names return tuple(Subject(load_key=name, label=name) for name in names)