Coverage for src / ezcompiler / utils / validators / value_validators.py: 100.00%
43 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-27 06:49 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-27 06:49 +0000
1# ///////////////////////////////////////////////////////////////
2# VALUE_VALIDATORS - Value validation utilities
3# Project: ezcompiler
4# ///////////////////////////////////////////////////////////////
6"""
7Value validators - Validation utilities for value ranges and constraints.
9This module provides validation functions for checking string lengths,
10numeric ranges, list lengths, choices, and other value constraints.
11"""
13from __future__ import annotations
15# ///////////////////////////////////////////////////////////////
16# IMPORTS
17# ///////////////////////////////////////////////////////////////
18# Standard library imports
19from typing import Any
21# Local imports
22from ...shared.exceptions.utils.validation_exceptions import (
23 ChoiceValidationError,
24 LengthValidationError,
25 RangeValidationError,
26 RequiredFieldError,
27)
29# ///////////////////////////////////////////////////////////////
30# FUNCTIONS
31# ///////////////////////////////////////////////////////////////
34def validate_string_length(
35 value: str, min_length: int = 0, max_length: int | None = None
36) -> bool:
37 """
38 Validate string length.
40 Args:
41 value: String to validate
42 min_length: Minimum allowed length (default: 0)
43 max_length: Maximum allowed length, None for no limit (default: None)
45 Returns:
46 bool: True if string length is valid, False otherwise
48 Example:
49 >>> validate_string_length("hello", min_length=3)
50 True
51 >>> validate_string_length("hi", min_length=3)
52 False
53 >>> validate_string_length("toolong", max_length=5)
54 False
55 """
56 if not isinstance(value, str):
57 return False
59 if len(value) < min_length:
60 return False
62 return not (max_length is not None and len(value) > max_length)
65def validate_numeric_range(
66 value: int | float,
67 min_value: int | float | None = None,
68 max_value: int | float | None = None,
69) -> bool:
70 """
71 Validate numeric value range.
73 Args:
74 value: Numeric value to validate
75 min_value: Minimum allowed value, None for no limit (default: None)
76 max_value: Maximum allowed value, None for no limit (default: None)
78 Returns:
79 bool: True if value is within range, False otherwise
81 Example:
82 >>> validate_numeric_range(5, min_value=0, max_value=10)
83 True
84 >>> validate_numeric_range(-1, min_value=0)
85 False
86 >>> validate_numeric_range(15, max_value=10)
87 False
88 """
89 if not isinstance(value, (int, float)):
90 return False
92 if min_value is not None and value < min_value:
93 return False
95 return not (max_value is not None and value > max_value)
98def validate_list_length(
99 value: list[Any], min_length: int = 0, max_length: int | None = None
100) -> bool:
101 """
102 Validate list length.
104 Args:
105 value: List to validate
106 min_length: Minimum allowed length (default: 0)
107 max_length: Maximum allowed length, None for no limit (default: None)
109 Returns:
110 bool: True if list length is valid, False otherwise
112 Example:
113 >>> validate_list_length([1, 2, 3], min_length=2)
114 True
115 >>> validate_list_length([1], min_length=2)
116 False
117 >>> validate_list_length([1, 2, 3, 4], max_length=3)
118 False
119 """
120 if not isinstance(value, list):
121 return False
123 if len(value) < min_length:
124 return False
126 return not (max_length is not None and len(value) > max_length)
129def validate_choice(value: Any, valid_choices: list[Any]) -> bool:
130 """
131 Validate that a value is one of the valid choices.
133 Args:
134 value: Value to validate
135 valid_choices: List of valid choices
137 Returns:
138 bool: True if value is a valid choice, False otherwise
140 Example:
141 >>> validate_choice("red", ["red", "green", "blue"])
142 True
143 >>> validate_choice("yellow", ["red", "green", "blue"])
144 False
145 """
146 return value in valid_choices
149def validate_not_empty(value: Any, field_name: str = "Value") -> None:
150 """
151 Validate that a value is not empty (string, list, dict, etc.).
153 Args:
154 value: Value to validate
155 field_name: Name of field for error messages
157 Raises:
158 RequiredFieldError: If value is empty
160 Example:
161 >>> validate_not_empty("hello")
162 >>> validate_not_empty([1, 2, 3])
163 >>> validate_not_empty("")
164 Traceback (most recent call last):
165 ...
166 RequiredFieldError: Value cannot be empty
167 """
168 if not value:
169 raise RequiredFieldError(f"{field_name} cannot be empty")
172def validate_one_of(
173 value: Any, valid_values: list[Any], field_name: str = "Value"
174) -> None:
175 """
176 Validate that a value is one of the valid options.
178 Args:
179 value: Value to validate
180 valid_values: List of valid values
181 field_name: Name of field for error messages
183 Raises:
184 ChoiceValidationError: If value is not in valid values
186 Example:
187 >>> validate_one_of("red", ["red", "green", "blue"])
188 >>> validate_one_of("yellow", ["red", "green", "blue"])
189 Traceback (most recent call last):
190 ...
191 ChoiceValidationError: Value must be one of: red, green, blue, got yellow
192 """
193 if value not in valid_values:
194 valid_str = ", ".join(str(v) for v in valid_values)
195 raise ChoiceValidationError(
196 f"{field_name} must be one of: {valid_str}, got {value}"
197 )
200def validate_value_in_range(
201 value: int | float,
202 min_value: int | float | None = None,
203 max_value: int | float | None = None,
204 field_name: str = "Value",
205) -> None:
206 """
207 Validate that a numeric value is within a range.
209 Args:
210 value: Numeric value to validate
211 min_value: Minimum allowed value (None for no limit)
212 max_value: Maximum allowed value (None for no limit)
213 field_name: Name of field for error messages
215 Raises:
216 RangeValidationError: If value is out of range
218 Example:
219 >>> validate_value_in_range(5, min_value=0, max_value=10)
220 >>> validate_value_in_range(-1, min_value=0)
221 Traceback (most recent call last):
222 ...
223 RangeValidationError: Value must be >= 0, got -1
224 """
225 if min_value is not None and value < min_value:
226 raise RangeValidationError(f"{field_name} must be >= {min_value}, got {value}")
227 if max_value is not None and value > max_value:
228 raise RangeValidationError(f"{field_name} must be <= {max_value}, got {value}")
231def validate_length(
232 value: str | list[Any],
233 min_length: int | None = None,
234 max_length: int | None = None,
235 field_name: str = "Value",
236) -> None:
237 """
238 Validate the length of a string or list.
240 Args:
241 value: String or list to validate
242 min_length: Minimum allowed length (None for no limit)
243 max_length: Maximum allowed length (None for no limit)
244 field_name: Name of field for error messages
246 Raises:
247 TypeError: If value is not string or list
248 LengthValidationError: If length is out of range
250 Example:
251 >>> validate_length("hello", min_length=3, max_length=10)
252 >>> validate_length("hi", min_length=3)
253 Traceback (most recent call last):
254 ...
255 LengthValidationError: Value must have length >= 3, got 2
256 """
257 if not isinstance(value, (str, list)):
258 raise TypeError(f"{field_name} must be string or list")
260 length = len(value)
261 if min_length is not None and length < min_length:
262 raise LengthValidationError(
263 f"{field_name} must have length >= {min_length}, got {length}"
264 )
265 if max_length is not None and length > max_length:
266 raise LengthValidationError(
267 f"{field_name} must have length <= {max_length}, got {length}"
268 )