Skip to content

Commit 2e35816

Browse files
committed
remove from_attributes logic from type-dict validator
1 parent 4cf41ae commit 2e35816

File tree

5 files changed

+55
-467
lines changed

5 files changed

+55
-467
lines changed

pydantic_core/core_schema.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2659,7 +2659,6 @@ class TypedDictSchema(TypedDict, total=False):
26592659
extra_behavior: ExtraBehavior
26602660
total: bool # default: True
26612661
populate_by_name: bool # replaces `allow_population_by_field_name` in pydantic v1
2662-
from_attributes: bool
26632662
ref: str
26642663
metadata: Any
26652664
serialization: SerSchema
@@ -2674,7 +2673,6 @@ def typed_dict_schema(
26742673
extra_behavior: ExtraBehavior | None = None,
26752674
total: bool | None = None,
26762675
populate_by_name: bool | None = None,
2677-
from_attributes: bool | None = None,
26782676
ref: str | None = None,
26792677
metadata: Any = None,
26802678
serialization: SerSchema | None = None,
@@ -2702,7 +2700,6 @@ def typed_dict_schema(
27022700
extra_behavior: The extra behavior to use for the typed dict
27032701
total: Whether the typed dict is total
27042702
populate_by_name: Whether the typed dict should populate by name
2705-
from_attributes: Whether the typed dict should be populated from attributes
27062703
serialization: Custom serialization schema
27072704
"""
27082705
return dict_not_none(
@@ -2714,7 +2711,6 @@ def typed_dict_schema(
27142711
extra_behavior=extra_behavior,
27152712
total=total,
27162713
populate_by_name=populate_by_name,
2717-
from_attributes=from_attributes,
27182714
ref=ref,
27192715
metadata=metadata,
27202716
serialization=serialization,

src/validators/typed_dict.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ pub struct TypedDictValidator {
3030
extra_behavior: ExtraBehavior,
3131
extra_validator: Option<Box<CombinedValidator>>,
3232
strict: bool,
33-
from_attributes: bool,
3433
loc_by_alias: bool,
3534
}
3635

@@ -47,7 +46,6 @@ impl BuildValidator for TypedDictValidator {
4746

4847
let total =
4948
schema_or_config(schema, config, intern!(py, "total"), intern!(py, "typed_dict_total"))?.unwrap_or(true);
50-
let from_attributes = schema_or_config_same(schema, config, intern!(py, "from_attributes"))?.unwrap_or(false);
5149
let populate_by_name = schema_or_config_same(schema, config, intern!(py, "populate_by_name"))?.unwrap_or(false);
5250

5351
let extra_behavior = ExtraBehavior::from_schema_or_config(py, schema, config, ExtraBehavior::Ignore)?;
@@ -119,7 +117,6 @@ impl BuildValidator for TypedDictValidator {
119117
extra_behavior,
120118
extra_validator,
121119
strict,
122-
from_attributes,
123120
loc_by_alias: config.get_as(intern!(py, "loc_by_alias"))?.unwrap_or(true),
124121
}
125122
.into())
@@ -136,7 +133,7 @@ impl Validator for TypedDictValidator {
136133
recursion_guard: &'s mut RecursionGuard,
137134
) -> ValResult<'data, PyObject> {
138135
let strict = extra.strict.unwrap_or(self.strict);
139-
let dict = input.validate_model_fields(strict, self.from_attributes)?;
136+
let dict = input.validate_dict(strict)?;
140137

141138
let output_dict = PyDict::new(py);
142139
let mut errors: Vec<ValLineError> = Vec::with_capacity(self.fields.len());

tests/validators/test_definitions_recursive.py

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -361,10 +361,6 @@ def test_recursion_branch():
361361
'branch': {'name': 'b1', 'branch': None},
362362
}
363363

364-
data = Cls(name='root')
365-
data.branch = Cls(name='b1', branch=None)
366-
assert v.validate_python(data) == {'name': 'root', 'branch': {'name': 'b1', 'branch': None}}
367-
368364
b = {'name': 'recursive'}
369365
b['branch'] = b
370366
with pytest.raises(ValidationError) as exc_info:
@@ -379,6 +375,40 @@ def test_recursion_branch():
379375
}
380376
]
381377

378+
379+
def test_recursion_branch_from_attributes():
380+
v = SchemaValidator(
381+
{
382+
'type': 'model-fields',
383+
'ref': 'Branch',
384+
'fields': {
385+
'name': {'type': 'model-field', 'schema': {'type': 'str'}},
386+
'branch': {
387+
'type': 'model-field',
388+
'schema': {
389+
'type': 'default',
390+
'schema': {'type': 'nullable', 'schema': {'type': 'definition-ref', 'schema_ref': 'Branch'}},
391+
'default': None,
392+
},
393+
},
394+
},
395+
},
396+
{'from_attributes': True},
397+
)
398+
399+
assert v.validate_python({'name': 'root'}) == ({'name': 'root', 'branch': None}, None, {'name'})
400+
model_dict, model_extra, fields_set = v.validate_python({'name': 'root', 'branch': {'name': 'b1', 'branch': None}})
401+
assert model_dict == {'name': 'root', 'branch': ({'name': 'b1', 'branch': None}, None, {'name', 'branch'})}
402+
assert model_extra is None
403+
assert fields_set == {'name', 'branch'}
404+
405+
data = Cls(name='root')
406+
data.branch = Cls(name='b1', branch=None)
407+
model_dict, model_extra, fields_set = v.validate_python(data)
408+
assert model_dict == {'name': 'root', 'branch': ({'name': 'b1', 'branch': None}, None, {'name', 'branch'})}
409+
assert model_extra is None
410+
assert fields_set == {'name', 'branch'}
411+
382412
data = Cls(name='root')
383413
data.branch = data
384414
with pytest.raises(ValidationError) as exc_info:

tests/validators/test_tagged_union.py

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -437,27 +437,35 @@ def test_from_attributes():
437437
'discriminator': 'foobar',
438438
'choices': {
439439
'apple': {
440-
'type': 'typed-dict',
440+
'type': 'model-fields',
441441
'fields': {
442-
'a': {'type': 'typed-dict-field', 'schema': {'type': 'str'}},
443-
'b': {'type': 'typed-dict-field', 'schema': {'type': 'int'}},
442+
'a': {'type': 'model-field', 'schema': {'type': 'str'}},
443+
'b': {'type': 'model-field', 'schema': {'type': 'int'}},
444444
},
445445
},
446446
'banana': {
447-
'type': 'typed-dict',
447+
'type': 'model-fields',
448448
'fields': {
449-
'c': {'type': 'typed-dict-field', 'schema': {'type': 'str'}},
450-
'd': {'type': 'typed-dict-field', 'schema': {'type': 'int'}},
449+
'c': {'type': 'model-field', 'schema': {'type': 'str'}},
450+
'd': {'type': 'model-field', 'schema': {'type': 'int'}},
451451
},
452452
},
453453
},
454454
},
455455
{'from_attributes': True},
456456
)
457-
assert v.validate_python({'foobar': 'apple', 'a': 'apple', 'b': '13'}) == {'a': 'apple', 'b': 13}
458-
assert v.validate_python(Cls(foobar='apple', a='apple', b='13')) == {'a': 'apple', 'b': 13}
459-
assert v.validate_python({'foobar': 'banana', 'c': 'banana', 'd': '31'}) == {'c': 'banana', 'd': 31}
460-
assert v.validate_python(Cls(foobar='banana', c='banana', d='31')) == {'c': 'banana', 'd': 31}
457+
assert v.validate_python({'foobar': 'apple', 'a': 'apple', 'b': '13'}) == (
458+
{'a': 'apple', 'b': 13},
459+
None,
460+
{'a', 'b'},
461+
)
462+
assert v.validate_python(Cls(foobar='apple', a='apple', b='13')) == ({'a': 'apple', 'b': 13}, None, {'a', 'b'})
463+
assert v.validate_python({'foobar': 'banana', 'c': 'banana', 'd': '31'}) == (
464+
{'c': 'banana', 'd': 31},
465+
None,
466+
{'c', 'd'},
467+
)
468+
assert v.validate_python(Cls(foobar='banana', c='banana', d='31')) == ({'c': 'banana', 'd': 31}, None, {'c', 'd'})
461469

462470

463471
def test_use_ref():

0 commit comments

Comments
 (0)