diff --git a/src/evaluate/__init__.py b/src/evaluate/__init__.py index a8c25bd9..96745b6f 100644 --- a/src/evaluate/__init__.py +++ b/src/evaluate/__init__.py @@ -45,7 +45,7 @@ from .info import ComparisonInfo, EvaluationModuleInfo, MeasurementInfo, MetricInfo from .inspect import inspect_evaluation_module, list_evaluation_modules from .loading import load -from .module import CombinedEvaluations, Comparison, EvaluationModule, Measurement, Metric, combine +from .module import CombinedEvaluations, Comparison, EvaluationModule, EvaluationModuleError, Measurement, Metric, combine from .saving import save from .utils import * from .utils import gradio, logging diff --git a/src/evaluate/module.py b/src/evaluate/module.py index ca38b9b1..e089451d 100644 --- a/src/evaluate/module.py +++ b/src/evaluate/module.py @@ -40,6 +40,22 @@ logger = get_logger(__name__) +class EvaluationModuleError(Exception): + """Exception raised when an :class:`EvaluationModule` computation fails. + + Wraps internal errors (e.g. from sklearn or numpy) so callers can catch + evaluate-specific failures without catching broad :exc:`Exception`. + + Example:: + + import evaluate + acc = evaluate.load("accuracy") + try: + acc.compute(predictions=[], references=[]) + except evaluate.EvaluationModuleError as e: + print(f"Metric computation failed: {e}") + """ + class FileFreeLock(BaseFileLock): """Thread lock until a file **cannot** be locked""" @@ -464,7 +480,14 @@ def compute(self, *, predictions=None, references=None, **kwargs) -> Optional[di inputs = {input_name: self.data[input_name][:] for input_name in self._feature_names()} with temp_seed(self.seed): - output = self._compute(**inputs, **compute_kwargs) + try: + output = self._compute(**inputs, **compute_kwargs) + except EvaluationModuleError: + raise + except Exception as e: + raise EvaluationModuleError( + f"Metric computation failed for '{self.name}': {e}" + ) from e if self.buf_writer is not None: self.buf_writer = None