Skip to content

Commit a0bfacc

Browse files
committed
add back missing logic
1 parent 6bfc32f commit a0bfacc

File tree

1 file changed

+29
-1
lines changed

1 file changed

+29
-1
lines changed

src/validators/enum_.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
// Validator for Enums, so named because "enum" is a reserved keyword in Rust.
22
use std::marker::PhantomData;
33

4+
use pyo3::exceptions::PyTypeError;
45
use pyo3::intern;
56
use pyo3::prelude::*;
67
use pyo3::types::{PyDict, PyFloat, PyInt, PyList, PyString, PyType};
78

89
use crate::build_tools::{is_strict, py_schema_err};
910
use crate::errors::{ErrorType, ValError, ValResult};
1011
use crate::input::Input;
11-
use crate::tools::SchemaDict;
12+
use crate::tools::{safe_repr, SchemaDict};
1213

1314
use super::is_instance::class_repr;
1415
use super::literal::{expected_repr_name, LiteralLookup};
@@ -118,7 +119,34 @@ impl<T: EnumValidateValue> Validator for EnumValidator<T> {
118119
} else if let Some(v) = T::validate_value(py, input, &self.lookup, strict)? {
119120
state.floor_exactness(Exactness::Lax);
120121
return Ok(v);
122+
} else if let Some(ref missing) = self.missing {
123+
state.floor_exactness(Exactness::Lax);
124+
let enum_value = missing.bind(py).call1((input.to_object(py),)).map_err(|_| {
125+
ValError::new(
126+
ErrorType::Enum {
127+
expected: self.expected_repr.clone(),
128+
context: None,
129+
},
130+
input,
131+
)
132+
})?;
133+
// check enum_value is an instance of the class like
134+
// https://github.com/python/cpython/blob/v3.12.2/Lib/enum.py#L1148
135+
if enum_value.is_instance(class)? {
136+
return Ok(enum_value.into());
137+
} else if !enum_value.is(&py.None()) {
138+
let type_error = PyTypeError::new_err(format!(
139+
"error in {}._missing_: returned {} instead of None or a valid member",
140+
class
141+
.name()
142+
.and_then(|name| name.extract::<String>())
143+
.unwrap_or_else(|_| "<Unknown>".into()),
144+
safe_repr(&enum_value)
145+
));
146+
return Err(type_error.into());
147+
}
121148
} else if let Ok(res) = class.as_unbound().call1(py, (input.as_python(),)) {
149+
// as a last result, just try to initialize the enum with the input
122150
state.floor_exactness(Exactness::Lax);
123151
return Ok(res);
124152
}

0 commit comments

Comments
 (0)