src.pydasa.validations.decorators#
Decorator-based validation system for PyDASA property setters, reducing boilerplate code with reusable validation logic.
- Functions:
validate_type: Validates value against expected type(s).
validate_emptiness: Ensures string values are non-empty.
validate_choices: Validates value is in allowed set of choices.
validate_range: Validates numeric value is within specified range.
validate_index: Validates integer values with negativity control.
validate_pattern: Validates string matches regex pattern(s) or is alphanumeric.
validate_custom: Custom validation logic.
Functions#
|
Decorator to validate argument type against expected type(s). |
|
Decorator to ensure values are non-empty. |
|
Decorator to validate value is in allowed set of choices. |
|
Decorator to validate integer values with negativity and zero control. |
|
Decorator to validate numeric value is within specified range. |
|
Decorator to validate string matches regex pattern(s) or is alphanumeric. |
|
Decorator to validate list contains only specified element types. It asumes the list exists. |
|
Decorator to validate dict has correct key and value types. It asumes the dict exists. |
|
Decorator for custom validation logic. Allows implementing custom validation logic by providing a validator function. |
Module Contents#
- src.pydasa.validations.decorators.validate_type(*expected_types, allow_none=True, allow_nan=False)#
Decorator to validate argument type against expected type(s).
- Parameters:
- Raises:
ValueError – If value is None when allow_none is False.
ValueError – If value is np.nan when allow_nan is False.
ValueError – If value type does not match any of the expected types.
- Returns:
Decorated function with type validation.
- Return type:
Callable
Example:
@property def unit(self) -> str: return self._unit @unit.setter @validate_type(str) def unit(self, val: str) -> None: self._unit = val # Multiple types @value.setter @validate_type(int, float) def value(self, val: Union[int, float]) -> None: self._value = val # Allow np.nan @mean.setter @validate_type(int, float, allow_nan=True) def mean(self, val: Optional[float]) -> None: self._mean = val
- src.pydasa.validations.decorators.validate_emptiness(strip=True)#
Decorator to ensure values are non-empty.
Handles strings, dictionaries, lists, tuples, and other collections. For strings, optionally strips whitespace before checking.
- Parameters:
strip (bool, optional) – Whether to strip whitespace before checking strings. Defaults to True.
- Raises:
ValueError – If string is empty/whitespace-only, or if collection has no elements.
- Returns:
Decorated function with non-empty validation.
- Return type:
Callable
Example:
@unit.setter @validate_type(str) @validate_emptiness() def unit(self, val: str) -> None: self._unit = val @variables.setter @validate_type(dict) @validate_emptiness() def variables(self, val: dict) -> None: self._variables = val
- src.pydasa.validations.decorators.validate_choices(choices, allow_none=False, case_sensitive=False)#
Decorator to validate value is in allowed set of choices.
- Parameters:
- Raises:
ValueError – If value is not in the allowed choices.
- Returns:
Decorated function with choice validation.
- Return type:
Callable
Example:
from pydasa.core.setup import Frameworks @fwk.setter @validate_type(str) @validate_choices(Frameworks.values()) def fwk(self, val: str) -> None: self._fwk = val.upper() # Case-sensitive choices @status.setter @validate_choices(["Active", "Inactive"], case_sensitive=True) def status(self, val: str) -> None: self._status = val
- src.pydasa.validations.decorators.validate_index(allow_zero=True, allow_negative=False)#
Decorator to validate integer values with negativity and zero control.
- Parameters:
- Raises:
ValueError – If value is not an integer.
ValueError – If negative value when allow_negative is False.
ValueError – If zero value when allow_zero is False.
- Returns:
Decorated function with integer validation.
- Return type:
Callable
Example:
# Non-negative integers only @idx.setter @validate_index(allow_negative=False) def idx(self, val: int) -> None: self._idx = val # Positive integers only (no zero) @count.setter @validate_index(allow_negative=False, allow_zero=False) def count(self, val: int) -> None: self._count = val
- src.pydasa.validations.decorators.validate_range(min_value=None, max_value=None, min_inclusive=True, max_inclusive=True, min_attr=None, max_attr=None)#
Decorator to validate numeric value is within specified range.
- Parameters:
min_value (Optional[float], optional) – Static minimum value. Defaults to None.
max_value (Optional[float], optional) – Static maximum value. Defaults to None.
min_inclusive (bool, optional) – Whether minimum is inclusive (>=) or exclusive (>). Defaults to True.
max_inclusive (bool, optional) – Whether maximum is inclusive (<=) or exclusive (<). Defaults to True.
min_attr (Optional[str], optional) – Attribute name for dynamic minimum (e.g., ‘_min’). Defaults to None.
max_attr (Optional[str], optional) – Attribute name for dynamic maximum (e.g., ‘_max’). Defaults to None.
- Raises:
ValueError – If value is outside the specified range.
- Returns:
Decorated function with range validation.
- Return type:
Callable
Example:
# Static range @age.setter @validate_type(int) @validate_range(min_value=0, max_value=150) def age(self, val: int) -> None: self._age = val # Dynamic range based on other attributes @mean.setter @validate_type(int, float) @validate_range(min_attr='_min', max_attr='_max') def mean(self, val: float) -> None: self._mean = val
- src.pydasa.validations.decorators.validate_pattern(pattern=None, allow_alnum=False, error_msg=None, examples=None)#
Decorator to validate string matches regex pattern(s) or is alphanumeric.
This unified decorator handles: - Single pattern matching - Multiple pattern matching (OR logic - matches any pattern) - Optional alphanumeric validation - Scientific/mathematical symbols (alphanumeric OR LaTeX)
- Parameters:
pattern (Union[str, list, tuple]) – Single regex pattern string, or list/tuple of patterns to match (OR logic).
allow_alnum (bool, optional) – Whether to accept alphanumeric strings. Defaults to False.
error_msg (Optional[str], optional) – Custom error message (overrides default). Defaults to None.
examples (Optional[str], optional) – Example strings to show in error messages. Defaults to None.
- Raises:
ValueError – If value does not match any pattern and is not alphanumeric (when allowed).
- Returns:
Decorated function with pattern validation.
- Return type:
Callable
Examples:
# Simple pattern matching @code.setter @validate_pattern(r'^[A-Z]\d{3}$') def code(self, val: str) -> None: self._code = val # Symbol validation (alphanumeric OR LaTeX) from pydasa.validations.patterns import LATEX_RE @sym.setter @validate_type(str) @validate_emptiness() @validate_pattern(LATEX_RE, allow_alnum=True) def sym(self, val: str) -> None: self._sym = val # Multiple patterns (match any) @validate_pattern([r'^\\[a-z]+$', r'^\d+$']) def value(self, val: str) -> None: self._value = val
- src.pydasa.validations.decorators.validate_list_types(*elm_types)#
Decorator to validate list contains only specified element types. It asumes the list exists.
- Parameters:
*elm_types (type) – One or more expected types for list elements.
- Raises:
ValueError – If value is not a list.
ValueError – If list contains elements of wrong type.
- Returns:
Decorated function with list type validation.
- Return type:
Callable
Example:
@dim_col.setter @validate_type(list, allow_none=False) @validate_emptiness() @validate_list_types(int, float) def dim_col(self, val: List[int]) -> None: self._dim_col = [int(x) for x in val]
- src.pydasa.validations.decorators.validate_dict_types(key_type, val_types)#
Decorator to validate dict has correct key and value types. It asumes the dict exists.
- Parameters:
- Raises:
ValueError – If dict keys or values have wrong types.
- Returns:
Decorated function with dict type validation.
- Return type:
Callable
Example:
@variables.setter @validate_type(dict, allow_none=False) @validate_emptiness() @validate_dict_types(str, (Variable, dict)) def variables(self, val: Dict[str, Variable]) -> None: self._variables = val
- src.pydasa.validations.decorators.validate_custom(validator_func)#
Decorator for custom validation logic. Allows implementing custom validation logic by providing a validator function.
The validator function should raise ValueError if validation fails. NOTE: this is too abstract and should be used sparingly.
- Parameters:
validator_func (Callable[[Any, Any], None]) – Function(self, value) that raises ValueError if invalid.
- Raises:
ValueError – If custom validator function raises ValueError.
- Returns:
Decorated function with custom validation.
- Return type:
Callable
Example:
def check_range_consistency(self, value): '''Ensure minimum does not exceed maximum.''' if value is not None and self._max is not None and value > self._max: raise ValueError(f"min {value} > max {self._max}") @min.setter @validate_type(int, float) @validate_custom(check_range_consistency) def min(self, val: float) -> None: self._min = val