diff --git a/changes/2449-PrettyWood.md b/changes/2449-PrettyWood.md new file mode 100644 index 00000000000..1568805daa1 --- /dev/null +++ b/changes/2449-PrettyWood.md @@ -0,0 +1 @@ +fix validation with a `BaseModel` field and a custom root type diff --git a/pydantic/main.py b/pydantic/main.py index 5fd83f7bb9c..91e012b2312 100644 --- a/pydantic/main.py +++ b/pydantic/main.py @@ -717,11 +717,12 @@ def __get_validators__(cls) -> 'CallableGenerator': @classmethod def validate(cls: Type['Model'], value: Any) -> 'Model': + if isinstance(value, cls): + return value.copy() if cls.__config__.copy_on_model_validation else value + value = cls._enforce_dict_if_root(value) if isinstance(value, dict): return cls(**value) - elif isinstance(value, cls): - return value.copy() if cls.__config__.copy_on_model_validation else value elif cls.__config__.orm_mode: return cls.from_orm(value) else: diff --git a/tests/test_main.py b/tests/test_main.py index 51102160f93..23f5a0acdfc 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -17,6 +17,7 @@ ValidationError, constr, root_validator, + validate_model, validator, ) from pydantic.typing import Literal @@ -1137,6 +1138,17 @@ class MyModel(BaseModel): assert m.__root__ == ['a'] +def test_root_nested(): + class MyList(BaseModel): + __root__: List[str] + + class MyModel(BaseModel): + my_list: MyList + + my_list = MyList(__root__=['pika']) + assert MyModel(my_list=my_list).dict() == {'my_list': ['pika']} + + def test_encode_nested_root(): house_dict = {'pets': ['dog', 'cats']}