Repository: pydantic/pydantic

Issue:
Missing downwards compatibility and bug with custom root types
```py
from typing import Generic
from typing import TypeVar
from typing import List
from pydantic.generics import GenericModel
from pydantic import BaseModel

T = TypeVar("T")
class BaseList(GenericModel, Generic[T]):
     __root__: List[T]

class Test(BaseModel):
     mylist: BaseList[int]

Test(mylist=[1,2,3,4])
# Test(mylist=BaseList[int](__root__=[1, 2, 3, 4]))

Test(mylist=BaseList[int](__root__=[1,2,3,4]))
# ---------------------------------------------------------------------------
# ValidationError                           Traceback (most recent call last)
# <ipython-input-10-c373af038c5b> in <module>
# ----> 1 Test(mylist=BaseList[int](__root__=[1,2,3,4]))
# 
# /usr/local/lib/python3.8/dist-packages/pydantic/main.cpython-38-x86_64-linux-gnu.so in pydantic.main.BaseModel.__init__()
# 
# ValidationError: 1 validation error for Test
# mylist -> __root__
#   value is not a valid list (type=type_error.list)
```

Certainly no error with pydantic 1.6.1 (I tested this locally).
Probably also no errors with versions <1.8 because we have automatic tests in place with the newest package versions and these tests only fired yesterday.

On a first glance the documentation does not seem to have changed - so I assume also the behaviour should not have changed with the 1.8 release. See https://pydantic-docs.helpmanual.io/usage/models/#generic-models and 
https://pydantic-docs.helpmanual.io/usage/models/#custom-root-types

Output of `python -c "import pydantic.utils; print(pydantic.utils.version_info())"`:
```
             pydantic version: 1.8
            pydantic compiled: True
                 install path: /usr/local/lib/python3.8/dist-packages/pydantic
               python version: 3.8.0 (default, Oct 28 2019, 16:14:01)  [GCC 8.3.0]
                     platform: Linux-5.4.0-62-generic-x86_64-with-glibc2.27
     optional deps. installed: ['devtools', 'email-validator', 'typing-extensions']
...
```


Discussion:

Resolving patch:
diff --git a/pydantic/main.py b/pydantic/main.py
--- 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:


Test patch:
diff --git a/tests/test_main.py b/tests/test_main.py
--- a/tests/test_main.py
+++ b/tests/test_main.py
@@ -1137,6 +1137,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']}