From 2b70723db8ebee5502471e9edb1b20922225ca26 Mon Sep 17 00:00:00 2001 From: Deniz Ulker <156104354+uelkerd@users.noreply.github.com> Date: Thu, 25 Sep 2025 16:04:37 +0200 Subject: [PATCH] feat: add reusable CI validation utilities MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extracted from monster PR #171 as part of Phase 3A strategic decomposition. CI validation helpers providing: - Metric range validation (0-1 bounds checking) - Required keys validation with clear error messages - Attribute existence validation for objects - Declarative assertion helper for test conditions - Type-safe validation with specific exception types Reduces boilerplate in CI scripts and provides clearer failure semantics. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- scripts/ci/validation_utils.py | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/scripts/ci/validation_utils.py b/scripts/ci/validation_utils.py index 9b9f3bcc2..2c0c13f13 100644 --- a/scripts/ci/validation_utils.py +++ b/scripts/ci/validation_utils.py @@ -1,17 +1,18 @@ #!/usr/bin/env python3 -""" -Reusable validation helpers for CI scripts. +"""Reusable validation helpers for CI scripts. -These helpers reduce boilerplate and provide clearer failure semantics -using specific exception types. +These helpers reduce boilerplate and provide clearer failure semantics using specific +exception types. """ + from typing import Any, Iterable def validate_metric_ranges(metrics: dict[str, Any], fields: Iterable[str]) -> None: """Ensure each metric in fields is within [0, 1]. - Raises: + Raises + ------ ValueError: if any metric is missing or out of range. """ for field in fields: @@ -27,10 +28,15 @@ def validate_metric_ranges(metrics: dict[str, Any], fields: Iterable[str]) -> No raise ValueError(f"{pretty} should be between 0 and 1") -def validate_required_keys(obj: dict[str, Any], keys: Iterable[str], label: str = "object") -> None: +def validate_required_keys( + obj: dict[str, Any], + keys: Iterable[str], + label: str = "object", +) -> None: """Validate that all keys exist in obj. - Raises: + Raises + ------ KeyError: if a required key is missing. """ for key in keys: @@ -39,10 +45,15 @@ def validate_required_keys(obj: dict[str, Any], keys: Iterable[str], label: str raise KeyError(f"{label} should have {pretty}") -def validate_hasattrs(instance: Any, attrs: Iterable[str], label: str = "object") -> None: +def validate_hasattrs( + instance: Any, + attrs: Iterable[str], + label: str = "object", +) -> None: """Validate that instance has all attributes in attrs. - Raises: + Raises + ------ AttributeError: if a required attribute is missing. """ for attr in attrs: @@ -57,4 +68,3 @@ def ensure(condition: bool, message: str) -> None: """ if not condition: raise AssertionError(message) -