- Removed the existing `validation.py` file and replaced it with a modular structure, introducing separate files for validation results, field validators, and the base validator class. - Implemented comprehensive validation functions for common data types, enhancing reusability and maintainability. - Added a new `__init__.py` to expose the validation utilities, ensuring a clean public interface. - Created detailed documentation for the validation module, including usage examples and architectural details. - Introduced extensive unit tests to cover the new validation framework, ensuring reliability and preventing regressions. These changes enhance the overall architecture of the data validation module, making it more scalable and easier to manage.
113 lines
4.0 KiB
Python
113 lines
4.0 KiB
Python
"""
|
|
Validation result classes for data validation.
|
|
|
|
This module provides result classes used to represent validation outcomes
|
|
across the validation system.
|
|
"""
|
|
|
|
from typing import List, Any, Optional, Dict
|
|
|
|
|
|
class ValidationResult:
|
|
"""Simple validation result for individual field validation."""
|
|
|
|
def __init__(self,
|
|
is_valid: bool,
|
|
errors: List[str] = None,
|
|
warnings: List[str] = None,
|
|
sanitized_data: Any = None):
|
|
"""
|
|
Initialize validation result.
|
|
|
|
Args:
|
|
is_valid: Whether the validation passed
|
|
errors: List of error messages
|
|
warnings: List of warning messages
|
|
sanitized_data: Optional sanitized/normalized data
|
|
"""
|
|
self.is_valid = is_valid
|
|
self.errors = errors or []
|
|
self.warnings = warnings or []
|
|
self.sanitized_data = sanitized_data
|
|
|
|
def __str__(self) -> str:
|
|
"""String representation of validation result."""
|
|
status = "valid" if self.is_valid else "invalid"
|
|
details = []
|
|
if self.errors:
|
|
details.append(f"{len(self.errors)} errors")
|
|
if self.warnings:
|
|
details.append(f"{len(self.warnings)} warnings")
|
|
detail_str = f" with {', '.join(details)}" if details else ""
|
|
return f"ValidationResult: {status}{detail_str}"
|
|
|
|
def add_error(self, error: str) -> None:
|
|
"""Add an error message and set is_valid to False."""
|
|
self.errors.append(error)
|
|
self.is_valid = False
|
|
|
|
def add_warning(self, warning: str) -> None:
|
|
"""Add a warning message."""
|
|
self.warnings.append(warning)
|
|
|
|
def merge(self, other: 'ValidationResult') -> None:
|
|
"""Merge another validation result into this one."""
|
|
self.is_valid = self.is_valid and other.is_valid
|
|
self.errors.extend(other.errors)
|
|
self.warnings.extend(other.warnings)
|
|
# Don't merge sanitized data - it's context specific
|
|
|
|
|
|
class DataValidationResult:
|
|
"""Result of data validation - common across all exchanges."""
|
|
|
|
def __init__(self,
|
|
is_valid: bool,
|
|
errors: List[str],
|
|
warnings: List[str],
|
|
sanitized_data: Optional[Dict[str, Any]] = None):
|
|
"""
|
|
Initialize data validation result.
|
|
|
|
Args:
|
|
is_valid: Whether the validation passed
|
|
errors: List of error messages
|
|
warnings: List of warning messages
|
|
sanitized_data: Optional sanitized/normalized data dictionary
|
|
"""
|
|
self.is_valid = is_valid
|
|
self.errors = errors
|
|
self.warnings = warnings
|
|
self.sanitized_data = sanitized_data
|
|
|
|
def __str__(self) -> str:
|
|
"""String representation of data validation result."""
|
|
status = "valid" if self.is_valid else "invalid"
|
|
details = []
|
|
if self.errors:
|
|
details.append(f"{len(self.errors)} errors")
|
|
if self.warnings:
|
|
details.append(f"{len(self.warnings)} warnings")
|
|
if self.sanitized_data:
|
|
details.append("has sanitized data")
|
|
detail_str = f" with {', '.join(details)}" if details else ""
|
|
return f"DataValidationResult: {status}{detail_str}"
|
|
|
|
def add_error(self, error: str) -> None:
|
|
"""Add an error message and set is_valid to False."""
|
|
self.errors.append(error)
|
|
self.is_valid = False
|
|
|
|
def add_warning(self, warning: str) -> None:
|
|
"""Add a warning message."""
|
|
self.warnings.append(warning)
|
|
|
|
def merge(self, other: 'DataValidationResult') -> None:
|
|
"""Merge another data validation result into this one."""
|
|
self.is_valid = self.is_valid and other.is_valid
|
|
self.errors.extend(other.errors)
|
|
self.warnings.extend(other.warnings)
|
|
if other.sanitized_data:
|
|
if not self.sanitized_data:
|
|
self.sanitized_data = {}
|
|
self.sanitized_data.update(other.sanitized_data) |