2Validation for PyHelios DataTypes (vec2, vec3, vec4, colors, etc.)
4Provides comprehensive validation for all geometric data types,
5ensuring finite values and appropriate ranges before C++ operations.
9from .core
import is_finite_numeric
10from .exceptions
import ValidationError, create_validation_error
14 """Return the concrete vector class for a dimension count, or None if unknown.
16 Imported lazily to avoid a circular import (DataTypes imports validation).
18 from ..wrappers.DataTypes
import vec2, vec3, vec4
19 return {2: vec2, 3: vec3, 4: vec4}.get(expected_dims)
23 """Validate a color component is in valid range [0,1]."""
24 if not is_finite_numeric(value):
25 raise create_validation_error(
26 f
"Color component {component_name} must be a finite number, got {value} ({type(value).__name__})",
27 param_name=f
"{param_name}.{component_name}",
28 function_name=function_name,
29 expected_type=
"finite number in range [0,1]",
31 suggestion=
"Color components must be normalized values between 0 and 1."
34 if not (0.0 <= value <= 1.0):
35 raise create_validation_error(
36 f
"Color component {component_name}={value} is outside valid range [0,1]",
37 param_name=f
"{param_name}.{component_name}",
38 function_name=function_name,
39 expected_type=
"number in range [0,1]",
41 suggestion=
"Color components must be normalized values between 0 and 1."
45def validate_rgb_color(color: Any, param_name: str =
"color", function_name: str =
None):
47 Validate RGBcolor has finite values in [0,1] range.
50 color: RGBcolor object to validate
51 param_name: Parameter name for error messages
52 function_name: Function name for error messages
55 ValidationError: If color is invalid or components out of range
62 from ..wrappers.DataTypes
import RGBcolor
63 if not isinstance(color, RGBcolor):
64 raise create_validation_error(
65 f
"Parameter must be an RGBcolor, got {type(color).__name__}",
66 param_name=param_name,
67 function_name=function_name,
68 expected_type=
"RGBcolor",
70 suggestion=
"Use RGBcolor(r, g, b) where r, g, b are values between 0 and 1."
74 if not hasattr(color,
'r')
or not hasattr(color,
'g')
or not hasattr(color,
'b'):
75 raise create_validation_error(
76 f
"Parameter must be an RGBcolor object with .r, .g, .b attributes",
77 param_name=param_name,
78 function_name=function_name,
79 expected_type=
"RGBcolor",
81 suggestion=
"Use RGBcolor(r, g, b) where r, g, b are values between 0 and 1."
91 Validate RGBAcolor has finite values in [0,1] range.
94 color: RGBAcolor object to validate
95 param_name: Parameter name for error messages
96 function_name: Function name for error messages
99 ValidationError: If color is invalid or components out of range
105 if not hasattr(color,
'r')
or not hasattr(color,
'g')
or not hasattr(color,
'b')
or not hasattr(color,
'a'):
106 raise create_validation_error(
107 f
"Parameter must be an RGBAcolor object with .r, .g, .b, .a attributes",
108 param_name=param_name,
109 function_name=function_name,
110 expected_type=
"RGBAcolor",
112 suggestion=
"Use RGBAcolor(r, g, b, a) where all values are between 0 and 1."
121def validate_vector_finite(vector: Any, param_name: str =
"vector", expected_dims: int = 3, function_name: str =
None):
123 Validate vector has finite components.
126 vector: Vector object to validate (vec2, vec3, vec4, etc.)
127 param_name: Parameter name for error messages
128 expected_dims: Expected number of dimensions
129 function_name: Function name for error messages
132 ValidationError: If vector is invalid or has non-finite components
138 attrs = [
'x',
'y',
'z',
'w'][:expected_dims]
144 if expected_type
is not None and not isinstance(vector, expected_type):
145 raise create_validation_error(
146 f
"Parameter must be a vec{expected_dims}, got {type(vector).__name__}",
147 param_name=param_name,
148 function_name=function_name,
149 expected_type=f
"vec{expected_dims}",
151 suggestion=f
"Use vec{expected_dims}({', '.join(attrs)}) to construct this parameter."
156 if not hasattr(vector, attr):
157 raise create_validation_error(
158 f
"Parameter must be a vector with {'.'.join(attrs)} attributes",
159 param_name=param_name,
160 function_name=function_name,
161 expected_type=f
"vec{expected_dims}",
163 suggestion=f
"Use vec{expected_dims}() constructor or provide object with {'.'.join(attrs)} attributes."
166 value = getattr(vector, attr)
167 if not is_finite_numeric(value):
168 raise create_validation_error(
169 f
"Vector component {attr} must be a finite number, got {value} ({type(value).__name__})",
170 param_name=f
"{param_name}.{attr}",
171 function_name=function_name,
172 expected_type=
"finite number",
174 suggestion=
"Ensure all vector components are finite numbers (not NaN or infinity)."
178def validate_vec2(vector: Any, param_name: str =
"vector", function_name: str =
None):
180 Validate vec2 has finite x,y components.
183 vector: vec2 object to validate
184 param_name: Parameter name for error messages
185 function_name: Function name for error messages
188 The validated vec2 object
194def validate_vec3(vector: Any, param_name: str =
"vector", function_name: str =
None):
196 Validate vec3 has finite x,y,z components.
199 vector: vec3 object to validate
200 param_name: Parameter name for error messages
201 function_name: Function name for error messages
204 The validated vec3 object
210def validate_vec4(vector: Any, param_name: str =
"vector", function_name: str =
None):
212 Validate vec4 has finite x,y,z,w components.
215 vector: vec4 object to validate
216 param_name: Parameter name for error messages
217 function_name: Function name for error messages
224 Validate SphericalCoord has valid values.
227 coord: SphericalCoord object to validate
228 param_name: Parameter name for error messages
229 function_name: Function name for error messages
232 ValidationError: If coordinate has invalid values
237 if not hasattr(coord,
'radius')
or not hasattr(coord,
'elevation')
or not hasattr(coord,
'azimuth'):
238 raise create_validation_error(
239 f
"Parameter must be a SphericalCoord with .radius, .elevation, .azimuth attributes",
240 param_name=param_name,
241 function_name=function_name,
242 expected_type=
"SphericalCoord",
244 suggestion=
"Use SphericalCoord(radius, elevation, azimuth) constructor."
248 if not is_finite_numeric(coord.radius)
or coord.radius <= 0:
249 raise create_validation_error(
250 f
"SphericalCoord radius must be a positive finite number, got {coord.radius}",
251 param_name=f
"{param_name}.radius",
252 function_name=function_name,
253 expected_type=
"positive finite number",
254 actual_value=coord.radius,
255 suggestion=
"Radius must be greater than 0."
259 if not is_finite_numeric(coord.elevation):
260 raise create_validation_error(
261 f
"SphericalCoord elevation must be a finite number, got {coord.elevation} ({type(coord.elevation).__name__})",
262 param_name=f
"{param_name}.elevation",
263 function_name=function_name,
264 expected_type=
"finite number",
265 actual_value=coord.elevation,
266 suggestion=
"Elevation angle must be a finite number (not NaN or infinity)."
269 if not is_finite_numeric(coord.azimuth):
270 raise create_validation_error(
271 f
"SphericalCoord azimuth must be a finite number, got {coord.azimuth} ({type(coord.azimuth).__name__})",
272 param_name=f
"{param_name}.azimuth",
273 function_name=function_name,
274 expected_type=
"finite number",
275 actual_value=coord.azimuth,
276 suggestion=
"Azimuth angle must be a finite number (not NaN or infinity)."
280def validate_integer_vector(vector: Any, param_name: str =
"vector", expected_dims: int = 3, function_name: str =
None):
282 Validate integer vector (int2, int3, int4) has valid integer components.
285 vector: Integer vector object to validate
286 param_name: Parameter name for error messages
287 expected_dims: Expected number of dimensions
288 function_name: Function name for error messages
291 ValidationError: If vector has invalid or non-integer components
297 attrs = [
'x',
'y',
'z',
'w'][:expected_dims]
301 if not hasattr(vector, attr):
302 raise create_validation_error(
303 f
"Parameter must be an integer vector with {'.'.join(attrs)} attributes",
304 param_name=param_name,
305 function_name=function_name,
306 expected_type=f
"int{expected_dims}",
308 suggestion=f
"Use int{expected_dims}() constructor or provide object with {'.'.join(attrs)} attributes."
311 value = getattr(vector, attr)
312 if not isinstance(value, int):
313 raise create_validation_error(
314 f
"Integer vector component {attr} must be an integer, got {value} ({type(value).__name__})",
315 param_name=f
"{param_name}.{attr}",
316 function_name=function_name,
317 expected_type=
"integer",
319 suggestion=
"Ensure all vector components are integers."
323def validate_int2(vector: Any, param_name: str =
"vector", function_name: str =
None):
325 Validate int2 has valid integer x,y components.
328 vector: int2 object to validate
329 param_name: Parameter name for error messages
330 function_name: Function name for error messages
339def validate_int3(vector: Any, param_name: str =
"vector", function_name: str =
None):
341 Validate int3 has valid integer x,y,z components.
344 vector: int3 object to validate
345 param_name: Parameter name for error messages
346 function_name: Function name for error messages
351def validate_int4(vector: Any, param_name: str =
"vector", function_name: str =
None):
353 Validate int4 has valid integer x,y,z,w components.
356 vector: int4 object to validate
357 param_name: Parameter name for error messages
358 function_name: Function name for error messages
_expected_vector_type(int expected_dims)
Return the concrete vector class for a dimension count, or None if unknown.
validate_vector_finite(Any vector, str param_name="vector", int expected_dims=3, str function_name=None)
Validate vector has finite components.
validate_integer_vector(Any vector, str param_name="vector", int expected_dims=3, str function_name=None)
Validate integer vector (int2, int3, int4) has valid integer components.
validate_vec4(Any vector, str param_name="vector", str function_name=None)
Validate vec4 has finite x,y,z,w components.
validate_vec3(Any vector, str param_name="vector", str function_name=None)
Validate vec3 has finite x,y,z components.
validate_int4(Any vector, str param_name="vector", str function_name=None)
Validate int4 has valid integer x,y,z,w components.
validate_int3(Any vector, str param_name="vector", str function_name=None)
Validate int3 has valid integer x,y,z components.
validate_rgba_color(Any color, str param_name="color", str function_name=None)
Validate RGBAcolor has finite values in [0,1] range.
validate_int2(Any vector, str param_name="vector", str function_name=None)
Validate int2 has valid integer x,y components.
validate_vec2(Any vector, str param_name="vector", str function_name=None)
Validate vec2 has finite x,y components.
validate_rgb_color(Any color, str param_name="color", str function_name=None)
Validate RGBcolor has finite values in [0,1] range.
validate_spherical_coord(Any coord, str param_name="coordinate", str function_name=None)
Validate SphericalCoord has valid values.
validate_color_component(float value, str component_name, str param_name, str function_name=None)
Validate a color component is in valid range [0,1].