marshmallow-code / marshmallow-code/marshmallow
Inconsistent value type when validating nested schema fields
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 7.2k
- Forks
- 738
- Avg merge
- 1d 23h
- Merged PRs (30d)
- 7
Description
**Problem:**
When a Nested schema has a validation error its `@post_load` hooks are not invoked bypassing any transformations done there. This means the parent schema’s `@validates` and `@validate_schema` hooks have to deal with both the transformed and untransformed child values.
Originally I encountered this using `marshmallow-sqlalchemy` with `load_instance=True`.
**Steps to reproduce:**
The code below shows the problem.
```python
import dataclasses
import uuid
import marshmallow as ma
import pytest
@dataclasses.dataclass
class ChildModel:
uuid: uuid.UUID
name: str
class Child(ma.Schema):
uuid = ma.fields.UUID(required=True)
name = ma.fields.String(required=True)
@ma.post_load
def transform(self, data, **_kwargs):
return ChildModel(**data)
class Parent(ma.Schema):
child = ma.fields.Nested("Child")
@ma.validates("child")
def validate_child(self, value, **_kwargs):
if value:
# This fails when the child has a validation error as then its @post_load is not called.
assert isinstance(value, ChildModel)
def test_load_valid_uuid():
data = {"child": {"uuid": "c81505b4-258b-4912-b8bc-8ac913d56736", "name": "test"}}
result = Parent().load(data)
assert isinstance(result["child"], ChildModel)
def test_load_invalid_uuid():
data = {"child": {"uuid": "invalid-uuid", "name": "test"}}
with pytest.raises(ma.exceptions.ValidationError):
result = Parent().load(data)
```
When the child schema validates then `Parent.validate_child` is called with a ChildModel instance, but if the child data is invalid it gets called with a dict instance instead.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the Nested schema loading and validation flow represented by Parent, Child, and the @post_load and @validates hooks in the reproduction. Run the supplied pytest cases and trace why post_load is skipped for invalid child data. Done means parent validation sees a consistent child value type in both valid and invalid nested-data paths, with regression coverage for the reproduction.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend-api-design
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100