Repository: pydantic/pydantic

Issue:
Explicit validator in parent class breaks type validation in child class for nested types
# Question

Please complete:
* OS: Ubuntu 18.04
* Python version `import sys; print(sys.version)`: 3.6.8 [GCC 7.4.0]
* Pydantic version `import pydantic; print(pydantic.VERSION)`: 1.2a1

Hello, I'm trying to create an instance of class Bar.
```py
import pydantic
from typing import List


class Foo(pydantic.BaseModel):
    foo: List[List[int]]

    @pydantic.validator('foo')
    def check_something(cls, value):
        return value


class Bar(Foo):
    pass


foo_ = [[0, 1]]
Foo(foo=foo_)
Bar(foo=foo_)
```

Output:
```
pydantic.error_wrappers.ValidationError: 1 validation error for Bar
foo -> 0
  value is not a valid integer (type=type_error.integer)
```
There will be no error, If you remove validator.


Discussion:
Confirmed, thanks for reporting. Has been this way since v1.

I'll try and fix forthwith.

Resolving patch:
diff --git a/pydantic/fields.py b/pydantic/fields.py
--- a/pydantic/fields.py
+++ b/pydantic/fields.py
@@ -280,6 +280,12 @@ def alt_alias(self) -> bool:
         return self.name != self.alias
 
     def prepare(self) -> None:
+        """
+        Prepare the field but inspecting self.default, self.type_ etc.
+
+        Note: this method is **not** idempotent (because _type_analysis is not idempotent),
+        e.g. calling it it multiple times may modify the field and configure it incorrectly.
+        """
         if self.default is not None and self.type_ is None:
             self.type_ = type(self.default)
 
@@ -299,7 +305,7 @@ def prepare(self) -> None:
             self.allow_none = True
 
         self._type_analysis()
-        self._populate_validators()
+        self.populate_validators()
 
     def _type_analysis(self) -> None:  # noqa: C901 (ignore complexity)
         # typing interface is horrible, we have to do some ugly checks
@@ -403,7 +409,12 @@ def _create_sub_type(self, type_: AnyType, name: str, *, for_keys: bool = False)
             model_config=self.model_config,
         )
 
-    def _populate_validators(self) -> None:
+    def populate_validators(self) -> None:
+        """
+        Prepare self.pre_validators, self.validators, and self.post_validators based on self.type_'s  __get_validators__
+        and class validators. This method should be idempotent, e.g. it should be safe to call multiple times
+        without mis-configuring the field.
+        """
         class_validators_ = self.class_validators.values()
         if not self.sub_fields:
             get_validators = getattr(self.type_, '__get_validators__', None)
diff --git a/pydantic/main.py b/pydantic/main.py
--- a/pydantic/main.py
+++ b/pydantic/main.py
@@ -168,7 +168,7 @@ def __new__(mcs, name, bases, namespace, **kwargs):  # noqa C901
             if extra_validators:
                 f.class_validators.update(extra_validators)
                 # re-run prepare to add extra validators
-                f.prepare()
+                f.populate_validators()
 
         prepare_config(config, name)
 


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
@@ -1303,3 +1303,22 @@ class MyModel(BaseModel):
 
     m = MyModel(foo={'x': 'a', 'y': None})
     assert m.foo == {'x': 'a', 'y': None}
+
+
+def test_modify_fields():
+    class Foo(BaseModel):
+        foo: List[List[int]]
+
+        @validator('foo')
+        def check_something(cls, value):
+            return value
+
+    class Bar(Foo):
+        pass
+
+    # output is slightly different for 3.6
+    if sys.version_info >= (3, 7):
+        assert repr(Foo.__fields__['foo']) == "ModelField(name='foo', type=List[List[int]], required=True)"
+        assert repr(Bar.__fields__['foo']) == "ModelField(name='foo', type=List[List[int]], required=True)"
+    assert Foo(foo=[[0, 1]]).foo == [[0, 1]]
+    assert Bar(foo=[[0, 1]]).foo == [[0, 1]]