Skip to content

Commit

Permalink
revaliate models
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelcolvin committed Jul 18, 2022
1 parent 5c33ba0 commit 3f0cf92
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 1 deletion.
1 change: 1 addition & 0 deletions pydantic_core/_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class Config(TypedDict, total=False):
typed_dict_populate_by_name: bool # replaces `allow_population_by_field_name` in pydantic v1
# used on typed-dicts and tagged union keys
from_attributes: bool
revalidate_models: bool
# fields related to string fields only
str_max_length: int
str_min_length: int
Expand Down
22 changes: 22 additions & 0 deletions src/build_tools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,28 @@ impl<'py> SchemaDict<'py> for PyDict {
}
}

impl<'py> SchemaDict<'py> for Option<&PyDict> {
fn get_as<T>(&'py self, key: &str) -> PyResult<Option<T>>
where
T: FromPyObject<'py>,
{
match self {
Some(d) => d.get_as(key),
None => Ok(None),
}
}

fn get_as_req<T>(&'py self, key: &str) -> PyResult<T>
where
T: FromPyObject<'py>,
{
match self {
Some(d) => d.get_as_req(key),
None => py_error!(PyKeyError; "{}", key),
}
}
}

pub fn schema_or_config<'py, T>(
schema: &'py PyDict,
config: Option<&'py PyDict>,
Expand Down
10 changes: 9 additions & 1 deletion src/validators/model_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use super::{build_validator, BuildContext, BuildValidator, CombinedValidator, Ex
#[derive(Debug, Clone)]
pub struct ModelClassValidator {
strict: bool,
revalidate: bool,
validator: Box<CombinedValidator>,
class: Py<PyType>,
name: String,
Expand Down Expand Up @@ -46,6 +47,7 @@ impl BuildValidator for ModelClassValidator {
// we don't use is_strict here since we don't want validation to be strict in this case if
// `config.strict` is set, only if this specific field is strict
strict: schema.get_as("strict")?.unwrap_or(false),
revalidate: config.get_as("model_revalidate")?.unwrap_or(false),
validator: Box::new(validator),
class: class.into(),
// Get the class's `__name__`, not using `class.name()` since it uses `__qualname__`
Expand All @@ -67,7 +69,13 @@ impl Validator for ModelClassValidator {
) -> ValResult<'data, PyObject> {
let class = self.class.as_ref(py);
if input.is_type(class)? {
Ok(input.to_object(py))
if self.revalidate {
// TODO Need to copy __fields_set__
let output = self.validator.validate(py, input, extra, slots, recursion_guard)?;
Ok(self.create_class(py, output)?)
} else {
Ok(input.to_object(py))
}
} else if extra.strict.unwrap_or(self.strict) {
Err(ValError::new(
ErrorKind::ModelClassType {
Expand Down

0 comments on commit 3f0cf92

Please sign in to comment.