From e57807c3b3edf980fc0afecc93aaa4b408801875 Mon Sep 17 00:00:00 2001 From: Gregory Mulholland Date: Wed, 25 Mar 2026 13:31:51 -0700 Subject: [PATCH] Add raise_or_warn helper to centralize validation level logic Add a raise_or_warn() function to bounds_validation.py that centralizes the IGNORE/WARNING/FATAL pattern currently duplicated across has_quantities.py, has_template_check_generator.py, and others. Co-Authored-By: Claude Opus 4.6 (1M context) --- gemd/entity/bounds_validation.py | 28 +++++++++++++++++++++++++- tests/entity/test_bounds_validation.py | 27 ++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/gemd/entity/bounds_validation.py b/gemd/entity/bounds_validation.py index 3b8c039b..9a58412b 100644 --- a/gemd/entity/bounds_validation.py +++ b/gemd/entity/bounds_validation.py @@ -1,7 +1,11 @@ from enum import IntEnum from contextlib import contextmanager +from logging import getLogger -__all__ = ["WarningLevel", "get_validation_level", "set_validation_level", "validation_level"] +__all__ = ["WarningLevel", "get_validation_level", "set_validation_level", + "validation_level", "raise_or_warn"] + +logger = getLogger(__name__) class WarningLevel(IntEnum): @@ -43,3 +47,25 @@ def validation_level(level: WarningLevel): # Restore previous value BOUNDS_VALIDATION = old_value + + +def raise_or_warn(message, *, exc_class=ValueError, **kwargs): + """Raise, warn, or ignore based on the current validation level. + + Parameters + ---------- + message: str + The error/warning message. + exc_class: type + Exception class to raise when level is FATAL. + **kwargs: + Additional keyword arguments passed to the exception constructor. + + """ + level = get_validation_level() + if level == WarningLevel.IGNORE: + return + if level == WarningLevel.WARNING: + logger.warning(message) + else: + raise exc_class(message, **kwargs) diff --git a/tests/entity/test_bounds_validation.py b/tests/entity/test_bounds_validation.py index 28f2665f..fdf515ee 100644 --- a/tests/entity/test_bounds_validation.py +++ b/tests/entity/test_bounds_validation.py @@ -1,5 +1,9 @@ +import logging + +import pytest + from gemd.entity.bounds_validation import WarningLevel, set_validation_level, \ - get_validation_level, validation_level + get_validation_level, validation_level, raise_or_warn def test_bounds_validation(): @@ -9,3 +13,24 @@ def test_bounds_validation(): set_validation_level(WarningLevel.WARNING) assert get_validation_level() == WarningLevel.WARNING, "Setter worked." assert get_validation_level() == old_level, "Original level restored." + + +def test_raise_or_warn_ignore(): + """Verify raise_or_warn does nothing at IGNORE level.""" + with validation_level(WarningLevel.IGNORE): + raise_or_warn("should be ignored") # no exception, no warning + + +def test_raise_or_warn_warning(caplog): + """Verify raise_or_warn logs at WARNING level.""" + with validation_level(WarningLevel.WARNING): + with caplog.at_level(logging.WARNING): + raise_or_warn("check this") + assert "check this" in caplog.text + + +def test_raise_or_warn_fatal(): + """Verify raise_or_warn raises at FATAL level.""" + with validation_level(WarningLevel.FATAL): + with pytest.raises(ValueError, match="boom"): + raise_or_warn("boom")