diff --git a/src/validators/model_fields.rs b/src/validators/model_fields.rs index 3a334f571..17cbbf542 100644 --- a/src/validators/model_fields.rs +++ b/src/validators/model_fields.rs @@ -195,6 +195,9 @@ impl Validator for ModelFieldsValidator { } Err(err) => return Err(err), }; + + let state = &mut state.rebind_extra(|extra| extra.field_name = Some(field.name_py.bind(py).clone())); + if let Some((lookup_path, value)) = op_key_value { if let Some(ref mut used_keys) = used_keys { // key is "used" whether or not validation passes, since we want to skip this key in @@ -202,9 +205,6 @@ impl Validator for ModelFieldsValidator { used_keys.insert(lookup_path.first_key()); } - let state = - &mut state.rebind_extra(|extra| extra.field_name = Some(field.name_py.bind(py).clone())); - match field.validator.validate(py, value.borrow_input(), state) { Ok(value) => { model_dict.set_item(&field.name_py, value)?; diff --git a/tests/validators/test_with_default.py b/tests/validators/test_with_default.py index 2e2f36f36..e0bf3c3cf 100644 --- a/tests/validators/test_with_default.py +++ b/tests/validators/test_with_default.py @@ -967,3 +967,38 @@ def test_default_factory_not_called_union_ok(container_schema_builder) -> None: v = SchemaValidator(schema) s = SchemaSerializer(schema) assert s.to_python(v.validate_python({'a': 1}), mode='json') == {'a': 1, 'b': 2, 'c': 3} + + +def test_default_validate_default_after_validator_field_name() -> None: + class Model: + pass + + field_name: str | None = None + + def val_func(value, info: core_schema.ValidationInfo): + nonlocal field_name + field_name = info.field_name + return value + + schema = core_schema.model_schema( + cls=Model, + schema=core_schema.model_fields_schema( + fields={ + 'a': core_schema.model_field( + schema=core_schema.with_default_schema( + schema=core_schema.with_info_after_validator_function( + val_func, + schema=core_schema.str_schema(), + ), + default='default', + ) + ) + } + ), + config={'validate_default': True}, + ) + + val = SchemaValidator(schema) + val.validate_python({}) + + assert field_name == 'a'