Pydantic: Pydantic 1.6 does not validate nested models when using a default_factory

Created on 11 Jul 2020  路  5Comments  路  Source: samuelcolvin/pydantic

Bug

Output of python -c "import pydantic.utils; print(pydantic.utils.version_info())":

             pydantic version: 1.6
            pydantic compiled: True
                 install path: /usr/local/Caskroom/miniconda/base/envs/server/lib/python3.8/site-packages/pydantic
               python version: 3.8.3 (default, Jul  2 2020, 11:26:31)  [Clang 10.0.0 ]
                     platform: macOS-10.15.5-x86_64-i386-64bit
     optional deps. installed: ['typing-extensions']

I'm aware that validation does not apply to default values, but it appears that it is no longer applied to user-provided values that have a default factory value, either. If this is expected, I'm not sure if I saw it in the documentation or changelog.

from pydantic import BaseModel, Field
from typing import List

class Child(BaseModel):
    x: int

class Parent(BaseModel):
    children: List[Child] = Field(default_factory=list)


p = Parent(children=[{'x':1}, {'y':2}])

In Pydantic 1.5.1, an error is raised because the second child fails to validate (it is missing required value 'x')

In Pydantic 1.6, the Parent object is instantiated successfully and contains two dicts:

print(p)
# children=[{'x': 1}, {'y': 2}]

To avoid this and recover the expected behavior, validate_all must be set on the Parent class. However, since I'm providing the child value, I'm surprised that I had to ask for it to be validated.

bug

Most helpful comment

This is definitely a bug, probably caused by the changes in #1691, specifically removing alwasy=True from list and set child fields.

That it turn was required to solve a problem that came up in #1627.

I see that this is urgent, but I'm flat out with work, will try to fix when I can. @PrettyWood do you have any bright ideas how to solve this without a different regeression?

All 5 comments

This is definitely a bug, probably caused by the changes in #1691, specifically removing alwasy=True from list and set child fields.

That it turn was required to solve a problem that came up in #1627.

I see that this is urgent, but I'm flat out with work, will try to fix when I can. @PrettyWood do you have any bright ideas how to solve this without a different regeression?

Perhaps this is a consequence of the issue described in #1566 (and docs update #1592)? Does applying nested models implicitly set each_item=True with a default validator?

Ah sorry I see we just crossed messages. Ok, bittersweet glad to hear it :) I'll review the issues you linked and see what we can do in the meantime. Thank you!

Hmmm I see I'm sorry for that. This is definitely not expected! I'll have a look as soon as I can (probably on monday in the train).

Edit: the bug was way easier than I thought as it was only due to #1504. If any other has the same issue, do not hesitate to try out the fix to make sure there is no further regression.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

iwoloschin picture iwoloschin  路  3Comments

ashpreetbedi picture ashpreetbedi  路  3Comments

vvoody picture vvoody  路  3Comments

sbv-trueenergy picture sbv-trueenergy  路  3Comments

dmontagu picture dmontagu  路  3Comments