diff --git a/changes/1414-patrickkwang.md b/changes/1414-patrickkwang.md new file mode 100644 index 0000000000..898f5f8cd4 --- /dev/null +++ b/changes/1414-patrickkwang.md @@ -0,0 +1 @@ +Squash internal `__root__` dicts in `.dict()` (and, by extension, in `.json()`). \ No newline at end of file diff --git a/pydantic/main.py b/pydantic/main.py index 201ba6ed16..76c4008ba2 100644 --- a/pydantic/main.py +++ b/pydantic/main.py @@ -610,7 +610,7 @@ def _get_value( if isinstance(v, BaseModel): if to_dict: - return v.dict( + v_dict = v.dict( by_alias=by_alias, exclude_unset=exclude_unset, exclude_defaults=exclude_defaults, @@ -618,6 +618,9 @@ def _get_value( exclude=exclude, exclude_none=exclude_none, ) + if '__root__' in v_dict: + return v_dict['__root__'] + return v_dict else: return v.copy(include=include, exclude=exclude) diff --git a/tests/test_main.py b/tests/test_main.py index 32237d7672..e39d22df36 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -869,6 +869,26 @@ class MyModel(BaseModel): assert m.__root__ == ['a'] +def test_encode_nested_root(): + house_dict = {'pets': ['dog', 'cats']} + + class Pets(BaseModel): + __root__: List[str] + + class House(BaseModel): + pets: Pets + + assert House(**house_dict).dict() == house_dict + + class PetsDeep(BaseModel): + __root__: Pets + + class HouseDeep(BaseModel): + pets: PetsDeep + + assert HouseDeep(**house_dict).dict() == house_dict + + def test_root_failed(): with pytest.raises(ValueError, match='__root__ cannot be mixed with other fields'):