Source code for scarlet2.validation_utils

import logging
from dataclasses import dataclass
from typing import Any

from colorama import Back, Fore, Style

logger = logging.getLogger(__name__)

# A global switch that toggles automated validation checks.
VALIDATION_SWITCH = True


[docs] def set_validation(state: bool = True): """Set the global validation switch. Parameters ---------- state : bool, optional If True, validation checks will be automatically performed. If False, they will be skipped. Defaults to True. """ global VALIDATION_SWITCH VALIDATION_SWITCH = state logger.info(f"Automated validation checks are now {'enabled' if VALIDATION_SWITCH else 'disabled'}.")
@dataclass class ValidationResult: """Represents a validation result. This is the base dataclass that all the more specific Validation<Level> dataclasses inherit from. Generally, it should not be instantiated directly, but rather through the more specific ValidationInfo, ValidationWarning, or ValidationError classes. """ message: str check: str context: Any | None = None def __str__(self): base = f"{self.message}" if self.context is not None: base += f" | Context={self.context})" return base @dataclass class ValidationInfo(ValidationResult): """Represents a validation info message that is informative but not critical.""" def __str__(self): return f"{Style.BRIGHT}{Fore.BLACK}{Back.GREEN} INFO {Style.RESET_ALL} {super().__str__()}" @dataclass class ValidationWarning(ValidationResult): """Represents a validation warning that is not critical but should be noted.""" def __str__(self): return f"{Style.BRIGHT}{Fore.BLACK}{Back.YELLOW} WARN {Style.RESET_ALL} {super().__str__()}" @dataclass class ValidationError(ValidationResult): """Represents a validation error that is critical and should be addressed.""" def __str__(self): return f"{Style.BRIGHT}{Fore.WHITE}{Back.RED} ERROR {Style.RESET_ALL} {super().__str__()}" class ValidationMethodCollector(type): """Metaclass that collects all validation methods in a class into a single list. For any class that uses this metaclass, all methods that start with "check_" will be automatically collected into a class attribute named `validation_checks`. """ def __new__(cls, name, bases, namespace): """Creates a list of callable methods when a new instances of a class is created.""" cls = super().__new__(cls, name, bases, namespace) cls.validation_checks = [ attr for attr, value in namespace.items() if callable(value) and attr.startswith("check_") ] return cls def print_validation_results(preamble: str, results: list[ValidationResult]): """Print the validation results in a formatted manner. Parameters ---------- preamble : str A string to print before the validation results. results : list[_ValidationResult] A list of validation results to print. """ if len(results) == 0: return print( f"{preamble}:\n" + "\n".join(f"[{str(i).zfill(3)}] {str(result)}" for i, result in enumerate(results)) )