Skip to content

Commit

Permalink
Revert changes to model-fields and dataclass
Browse files Browse the repository at this point in the history
  • Loading branch information
uriyyo committed Dec 26, 2024
1 parent b9e0f5c commit 7642acc
Show file tree
Hide file tree
Showing 5 changed files with 1 addition and 140 deletions.
10 changes: 1 addition & 9 deletions python/pydantic_core/core_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class CoreConfig(TypedDict, total=False):
validate_default: bool
# used on typed-dicts and arguments
populate_by_name: bool # replaces `allow_population_by_field_name` in pydantic v1
# stop validation on a first error, used with typed-dict, model-fields, and dataclass fields
# stop validation on a first error, used with typed-dict
fail_fast: bool
# fields related to string fields only
str_max_length: int
Expand Down Expand Up @@ -3004,7 +3004,6 @@ class ModelFieldsSchema(TypedDict, total=False):
# all these values can be set via config, equivalent fields have `typed_dict_` prefix
extra_behavior: ExtraBehavior
populate_by_name: bool # replaces `allow_population_by_field_name` in pydantic v1
fail_fast: bool # default: False
from_attributes: bool
ref: str
metadata: Dict[str, Any]
Expand All @@ -3021,7 +3020,6 @@ def model_fields_schema(
extra_behavior: ExtraBehavior | None = None,
populate_by_name: bool | None = None,
from_attributes: bool | None = None,
fail_fast: bool | None = None,
ref: str | None = None,
metadata: Dict[str, Any] | None = None,
serialization: SerSchema | None = None,
Expand Down Expand Up @@ -3051,7 +3049,6 @@ def model_fields_schema(
extra_behavior: The extra behavior to use for the typed dict
populate_by_name: Whether the typed dict should populate by name
from_attributes: Whether the typed dict should be populated from attributes
fail_fast: Stop validation on the first error
serialization: Custom serialization schema
"""
return _dict_not_none(
Expand All @@ -3064,7 +3061,6 @@ def model_fields_schema(
extra_behavior=extra_behavior,
populate_by_name=populate_by_name,
from_attributes=from_attributes,
fail_fast=fail_fast,
ref=ref,
metadata=metadata,
serialization=serialization,
Expand Down Expand Up @@ -3248,7 +3244,6 @@ class DataclassArgsSchema(TypedDict, total=False):
fields: Required[List[DataclassField]]
computed_fields: List[ComputedField]
populate_by_name: bool # default: False
fail_fast: bool # default: False
collect_init_only: bool # default: False
ref: str
metadata: Dict[str, Any]
Expand All @@ -3262,7 +3257,6 @@ def dataclass_args_schema(
*,
computed_fields: List[ComputedField] | None = None,
populate_by_name: bool | None = None,
fail_fast: bool | None = None,
collect_init_only: bool | None = None,
ref: str | None = None,
metadata: Dict[str, Any] | None = None,
Expand Down Expand Up @@ -3291,7 +3285,6 @@ def dataclass_args_schema(
fields: The fields to use for the dataclass
computed_fields: Computed fields to use when serializing the dataclass
populate_by_name: Whether to populate by name
fail_fast: Stop validation on the first error
collect_init_only: Whether to collect init only fields into a dict to pass to `__post_init__`
ref: optional unique identifier of the schema, used to reference the schema in other places
metadata: Any other information you want to include with the schema, not used by pydantic-core
Expand All @@ -3304,7 +3297,6 @@ def dataclass_args_schema(
fields=fields,
computed_fields=computed_fields,
populate_by_name=populate_by_name,
fail_fast=fail_fast,
collect_init_only=collect_init_only,
ref=ref,
metadata=metadata,
Expand Down
11 changes: 0 additions & 11 deletions src/validators/dataclass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ pub struct DataclassArgsValidator {
validator_name: String,
extra_behavior: ExtraBehavior,
extras_validator: Option<Box<CombinedValidator>>,
fail_fast: bool,
loc_by_alias: bool,
}

Expand All @@ -55,7 +54,6 @@ impl BuildValidator for DataclassArgsValidator {
let py = schema.py();

let populate_by_name = schema_or_config_same(schema, config, intern!(py, "populate_by_name"))?.unwrap_or(false);
let fail_fast = schema_or_config_same(schema, config, intern!(py, "fail_fast"))?.unwrap_or(false);

let extra_behavior = ExtraBehavior::from_schema_or_config(py, schema, config, ExtraBehavior::Ignore)?;

Expand Down Expand Up @@ -130,7 +128,6 @@ impl BuildValidator for DataclassArgsValidator {
validator_name,
extra_behavior,
extras_validator,
fail_fast,
loc_by_alias: config.get_as(intern!(py, "loc_by_alias"))?.unwrap_or(true),
}
.into())
Expand Down Expand Up @@ -177,10 +174,6 @@ impl Validator for DataclassArgsValidator {

// go through fields getting the value from args or kwargs and validating it
for (index, field) in self.fields.iter().enumerate() {
if self.fail_fast && !errors.is_empty() {
break;
}

if !field.init {
match field.validator.default_value(py, Some(field.name.as_str()), state) {
Ok(Some(value)) => {
Expand Down Expand Up @@ -298,10 +291,6 @@ impl Validator for DataclassArgsValidator {
if let Some(kwargs) = args.kwargs() {
if kwargs.len() != used_keys.len() {
for result in kwargs.iter() {
if self.fail_fast && !errors.is_empty() {
break;
}

let (raw_key, value) = result?;
match raw_key
.borrow_input()
Expand Down
7 changes: 0 additions & 7 deletions src/validators/model_fields.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ pub struct ModelFieldsValidator {
strict: bool,
from_attributes: bool,
loc_by_alias: bool,
fail_fast: bool,
}

impl BuildValidator for ModelFieldsValidator {
Expand All @@ -52,7 +51,6 @@ impl BuildValidator for ModelFieldsValidator {

let from_attributes = schema_or_config_same(schema, config, intern!(py, "from_attributes"))?.unwrap_or(false);
let populate_by_name = schema_or_config_same(schema, config, intern!(py, "populate_by_name"))?.unwrap_or(false);
let fail_fast = schema_or_config_same(schema, config, intern!(py, "fail_fast"))?.unwrap_or(false);

let extra_behavior = ExtraBehavior::from_schema_or_config(py, schema, config, ExtraBehavior::Ignore)?;

Expand Down Expand Up @@ -104,7 +102,6 @@ impl BuildValidator for ModelFieldsValidator {
extras_validator,
strict,
from_attributes,
fail_fast,
loc_by_alias: config.get_as(intern!(py, "loc_by_alias"))?.unwrap_or(true),
}
.into())
Expand Down Expand Up @@ -171,10 +168,6 @@ impl Validator for ModelFieldsValidator {
let state = &mut state.rebind_extra(|extra| extra.data = Some(model_dict.clone()));

for field in &self.fields {
if self.fail_fast && !errors.is_empty() {
break;
}

let op_key_value = match dict.get_item(&field.lookup_key) {
Ok(v) => v,
Err(ValError::LineErrors(line_errors)) => {
Expand Down
60 changes: 0 additions & 60 deletions tests/validators/test_dataclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -1713,63 +1713,3 @@ class Foo:
assert exc_info.value.errors(include_url=False) == expected.errors
else:
assert dataclasses.asdict(v.validate_python(input_value)) == expected


@pytest.mark.parametrize(
('fail_fast', 'expected'),
[
pytest.param(
True,
[
{
'type': 'string_type',
'loc': ('a',),
'msg': 'Input should be a valid string',
'input': 10,
},
],
id='fail_fast',
),
pytest.param(
False,
[
{
'type': 'string_type',
'loc': ('a',),
'msg': 'Input should be a valid string',
'input': 10,
},
{
'type': 'string_type',
'loc': ('b',),
'msg': 'Input should be a valid string',
'input': 20,
},
],
id='not_fail_fast',
),
],
)
def test_dataclass_fail_fast(fail_fast, expected):
@dataclasses.dataclass
class Foo:
a: str
b: str

schema = core_schema.dataclass_schema(
Foo,
core_schema.dataclass_args_schema(
'Foo',
[
core_schema.dataclass_field(name='a', schema=core_schema.str_schema()),
core_schema.dataclass_field(name='b', schema=core_schema.str_schema()),
],
fail_fast=fail_fast,
),
['a', 'b'],
)

with pytest.raises(ValidationError) as exc_info:
SchemaValidator(schema).validate_python({'a': 10, 'b': 20})

assert exc_info.value.errors(include_url=False) == expected
53 changes: 0 additions & 53 deletions tests/validators/test_model_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -1781,56 +1781,3 @@ def test_extra_behavior_ignore(config: Union[core_schema.CoreConfig, None], sche
}
]
assert 'not_f' not in m


@pytest.mark.parametrize(
('fail_fast', 'expected'),
[
pytest.param(
True,
[
{
'input': 'x',
'loc': ('a',),
'msg': 'Input should be a valid integer, unable to parse string as an integer',
'type': 'int_parsing',
},
],
id='fail_fast',
),
pytest.param(
False,
[
{
'input': 'x',
'loc': ('a',),
'msg': 'Input should be a valid integer, unable to parse string as an integer',
'type': 'int_parsing',
},
{
'input': 'y',
'loc': ('b',),
'msg': 'Input should be a valid integer, unable to parse string as an integer',
'type': 'int_parsing',
},
],
id='not_fail_fast',
),
],
)
def test_model_fields_fail_fast(fail_fast, expected):
v = SchemaValidator(
{
'type': 'model-fields',
'fields': {
'a': {'type': 'model-field', 'schema': {'type': 'int'}},
'b': {'type': 'model-field', 'schema': {'type': 'int'}},
},
'fail_fast': fail_fast,
},
)

with pytest.raises(ValidationError) as exc_info:
v.validate_python({'a': 'x', 'b': 'y'})

assert exc_info.value.errors(include_url=False) == expected

0 comments on commit 7642acc

Please sign in to comment.