Skip to content

Commit 675a214

Browse files
committed
Consistent validation with complex number to float type coercion
1 parent 4c02cbd commit 675a214

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

src/input/input_python.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,18 @@ impl<'py> Input<'py> for Bound<'py, PyAny> {
291291
return Ok(ValidationMatch::exact(EitherFloat::Py(float.clone())));
292292
}
293293

294+
if self.is_instance_of::<PyComplex>() {
295+
if !strict {
296+
if let Ok(real) = self.getattr(intern!(self.py(), "real")) {
297+
if let Ok(float) = real.extract::<f64>() {
298+
return Ok(ValidationMatch::lax(EitherFloat::F64(float)));
299+
}
300+
}
301+
} else {
302+
return Err(ValError::new(ErrorTypeDefaults::FloatType, self));
303+
}
304+
}
305+
294306
if !strict {
295307
if let Some(s) = maybe_as_string(self, ErrorTypeDefaults::FloatParsing)? {
296308
// checking for bytes and string is fast, so do this before isinstance(float)

tests/validators/test_float.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
(False, 0),
3030
('wrong', Err('Input should be a valid number, unable to parse string as a number [type=float_parsing')),
3131
([1, 2], Err('Input should be a valid number [type=float_type, input_value=[1, 2], input_type=list]')),
32+
(1 + 0j, 1.0),
33+
(2.5 + 0j, 2.5),
34+
(3 + 1j, 3.0),
35+
(1j, 0),
3236
],
3337
)
3438
def test_float(py_and_json: PyAndJson, input_value, expected):
@@ -37,7 +41,10 @@ def test_float(py_and_json: PyAndJson, input_value, expected):
3741
with pytest.raises(ValidationError, match=re.escape(expected.message)):
3842
v.validate_test(input_value)
3943
else:
40-
output = v.validate_test(input_value)
44+
if isinstance(input_value, complex):
45+
output = v.validate_python(input_value)
46+
else:
47+
output = v.validate_test(input_value)
4148
assert output == expected
4249
assert isinstance(output, float)
4350

@@ -52,14 +59,21 @@ def test_float(py_and_json: PyAndJson, input_value, expected):
5259
(42.5, 42.5),
5360
('42', Err("Input should be a valid number [type=float_type, input_value='42', input_type=str]")),
5461
(True, Err('Input should be a valid number [type=float_type, input_value=True, input_type=bool]')),
62+
(1 + 0j, Err('Input should be a valid number [type=float_type, input_value=(1+0j), input_type=complex]')),
63+
(2.5 + 0j, Err('Input should be a valid number [type=float_type, input_value=(2.5+0j), input_type=complex]')),
64+
(3 + 1j, Err('Input should be a valid number [type=float_type, input_value=(3+1j), input_type=complex]')),
65+
(1j, Err('Input should be a valid number [type=float_type, input_value=1j, input_type=complex]')),
5566
],
5667
ids=repr,
5768
)
5869
def test_float_strict(py_and_json: PyAndJson, input_value, expected):
5970
v = py_and_json({'type': 'float', 'strict': True})
6071
if isinstance(expected, Err):
6172
with pytest.raises(ValidationError, match=re.escape(expected.message)):
62-
v.validate_test(input_value)
73+
if isinstance(input_value, complex):
74+
v.validate_python(input_value)
75+
else:
76+
v.validate_test(input_value)
6377
else:
6478
output = v.validate_test(input_value)
6579
assert output == expected

0 commit comments

Comments
 (0)