Repository: pydantic/pydantic

Issue:
Pydantic 1.6: fields with default_factory cause parse_obj() to set fields to unparsed values
# Bug

This is likely related to #1710 but does not explicitly involve validators. This would be a good candidate for a unit test to prevent future regressions.

Output of `python -c "import pydantic.utils; print(pydantic.utils.version_info())"`:
```
pydantic version: 1.6
pydantic compiled: True
install path: /usr/local/lib/python3.8/site-packages/pydantic
python version: 3.8.3 (default, May 16 2020, 07:08:28)  [GCC 8.3.0]
platform: Linux-4.15.0-109-generic-x86_64-with-glibc2.2.5
optional deps. installed: []
```
Here is a self-contained example illustrating the problem:
```py

from pydantic import BaseModel, Field

class Inner(BaseModel):
    val: int = Field(0)

class Outer(BaseModel):
    inner_1: Inner = Field(default_factory=Inner)
    inner_2: Inner = Field(Inner())

default = Outer().dict() # default == {'inner_1': {'val': 0}, 'inner_2': {'val': 0}}
parsed = Outer.parse_obj(default)

print(parsed)
```
In 1.6, this prints:
`inner_1={'value': 'default'} inner_2=Inner(value='default')`
Note that `inner_1` is a dict, not an `Inner` object!

In 1.5.1 this prints:
`inner_1=Inner(val=0) inner_2=Inner(val=0)`


Discussion:

Resolving patch:
diff --git a/benchmarks/run.py b/benchmarks/run.py
--- a/benchmarks/run.py
+++ b/benchmarks/run.py
@@ -274,6 +274,6 @@ def diff():
     else:
         main()
 
-    if None in other_tests:
-        print('not all libraries could be imported!')
-        sys.exit(1)
+    # if None in other_tests:
+    #     print('not all libraries could be imported!')
+    #     sys.exit(1)
diff --git a/pydantic/fields.py b/pydantic/fields.py
--- a/pydantic/fields.py
+++ b/pydantic/fields.py
@@ -341,8 +341,22 @@ def prepare(self) -> None:
         e.g. calling it it multiple times may modify the field and configure it incorrectly.
         """
 
-        # To prevent side effects by calling the `default_factory` for nothing, we only call it
-        # when we want to validate the default value i.e. when `validate_all` is set to True.
+        self._set_default_and_type()
+        self._type_analysis()
+        if self.required is Undefined:
+            self.required = True
+            self.field_info.default = Required
+        if self.default is Undefined and self.default_factory is None:
+            self.default = None
+        self.populate_validators()
+
+    def _set_default_and_type(self) -> None:
+        """
+        Set the default value, infer the type if needed and check if `None` value is valid.
+
+        Note: to prevent side effects by calling the `default_factory` for nothing, we only call it
+        when we want to validate the default value i.e. when `validate_all` is set to True.
+        """
         if self.default_factory is not None:
             if self.type_ is None:
                 raise errors_.ConfigError(
@@ -368,14 +382,6 @@ def prepare(self) -> None:
         if self.required is False and default_value is None:
             self.allow_none = True
 
-        self._type_analysis()
-        if self.required is Undefined:
-            self.required = True
-            self.field_info.default = Required
-        if self.default is Undefined and self.default_factory is None:
-            self.default = None
-        self.populate_validators()
-
     def _type_analysis(self) -> None:  # noqa: C901 (ignore complexity)
         # typing interface is horrible, we have to do some ugly checks
         if lenient_issubclass(self.type_, JsonWrapper):


Test patch:
diff --git a/tests/test_edge_cases.py b/tests/test_edge_cases.py
--- a/tests/test_edge_cases.py
+++ b/tests/test_edge_cases.py
@@ -1714,3 +1714,19 @@ class Config:
 
     m1 = MyModel()
     assert m1.id == 2  # instead of 1
+
+
+def test_default_factory_validator_child():
+    class Parent(BaseModel):
+        foo: List[str] = Field(default_factory=list)
+
+        @validator('foo', pre=True, each_item=True)
+        def mutate_foo(cls, v):
+            return f'{v}-1'
+
+    assert Parent(foo=['a', 'b']).foo == ['a-1', 'b-1']
+
+    class Child(Parent):
+        pass
+
+    assert Child(foo=['a', 'b']).foo == ['a-1', 'b-1']
diff --git a/tests/test_main.py b/tests/test_main.py
--- a/tests/test_main.py
+++ b/tests/test_main.py
@@ -1174,6 +1174,36 @@ class MyModel(BaseModel):
     assert m2.id == 2
 
 
+def test_default_factory_validate_children():
+    class Child(BaseModel):
+        x: int
+
+    class Parent(BaseModel):
+        children: List[Child] = Field(default_factory=list)
+
+    Parent(children=[{'x': 1}, {'x': 2}])
+    with pytest.raises(ValidationError) as exc_info:
+        Parent(children=[{'x': 1}, {'y': 2}])
+
+    assert exc_info.value.errors() == [
+        {'loc': ('children', 1, 'x'), 'msg': 'field required', 'type': 'value_error.missing'},
+    ]
+
+
+def test_default_factory_parse():
+    class Inner(BaseModel):
+        val: int = Field(0)
+
+    class Outer(BaseModel):
+        inner_1: Inner = Field(default_factory=Inner)
+        inner_2: Inner = Field(Inner())
+
+    default = Outer().dict()
+    parsed = Outer.parse_obj(default)
+    assert parsed.dict() == {'inner_1': {'val': 0}, 'inner_2': {'val': 0}}
+    assert repr(parsed) == 'Outer(inner_1=Inner(val=0), inner_2=Inner(val=0))'
+
+
 @pytest.mark.skipif(sys.version_info < (3, 7), reason='field constraints are set but not enforced with python 3.6')
 def test_none_min_max_items():
     # None default