Repository: samuelcolvin/pydantic
Pull request #4040 (2022-05-01 21:00:54)

build(deps): bump typing-extensions from 4.1.1 to 4.2.0
Bumps [typing-extensions](https://github.com/python/typing) from 4.1.1 to 4.2.0.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/python/typing/blob/master/typing_extensions/CHANGELOG.md">typing-extensions's changelog</a>.</em></p>
<blockquote>
<h1>Release 4.2.0 (April 17, 2022)</h1>
<ul>
<li>Re-export <code>typing.Unpack</code> and <code>typing.TypeVarTuple</code> on Python 3.11.</li>
<li>Add <code>ParamSpecArgs</code> and <code>ParamSpecKwargs</code> to <code>__all__</code>.</li>
<li>Improve &quot;accepts only single type&quot; error messages.</li>
<li>Improve the distributed package. Patch by Marc Mueller (<a href="https://github.com/cdce8p"><code>@​cdce8p</code></a>).</li>
<li>Update <code>typing_extensions.dataclass_transform</code> to rename the
<code>field_descriptors</code> parameter to <code>field_specifiers</code> and accept
arbitrary keyword arguments.</li>
<li>Add <code>typing_extensions.get_overloads</code> and
<code>typing_extensions.clear_overloads</code>, and add registry support to
<code>typing_extensions.overload</code>. Backport from <a href="https://github-redirect.dependabot.com/python/cpython/issues/89263">python/cpython#89263</a>.</li>
<li>Add <code>typing_extensions.assert_type</code>. Backport from bpo-46480.</li>
<li>Drop support for Python 3.6. Original patch by Adam Turner (<a href="https://github.com/AA-Turner"><code>@​AA-Turner</code></a>).</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/python/typing/commit/9a39406fa45fbfa76eb5d35afb7863f5f727ad87"><code>9a39406</code></a> prepare release 4.2.0 (<a href="https://github-redirect.dependabot.com/python/typing/issues/1144">#1144</a>)</li>
<li><a href="https://github.com/python/typing/commit/783c8ca10ffb8b2cd00e62977c052f8d5a31bc3f"><code>783c8ca</code></a> Fix tests on Python 3.11 (<a href="https://github-redirect.dependabot.com/python/typing/issues/1139">#1139</a>)</li>
<li><a href="https://github.com/python/typing/commit/2312c741154b61d5dfea3fa9f6b6f1adfb4b9aca"><code>2312c74</code></a> Add to the CHANGELOG (<a href="https://github-redirect.dependabot.com/python/typing/issues/1141">#1141</a>)</li>
<li><a href="https://github.com/python/typing/commit/b595c737c153a0d0f638be9d32469d043b7128a6"><code>b595c73</code></a> dataclass_transform: accept **kwargs, rename field_descriptors (<a href="https://github-redirect.dependabot.com/python/typing/issues/1120">#1120</a>)</li>
<li><a href="https://github.com/python/typing/commit/35dff91370a382e312dd53d002d948e3efedb317"><code>35dff91</code></a> Add get_overloads() (<a href="https://github-redirect.dependabot.com/python/typing/issues/1140">#1140</a>)</li>
<li><a href="https://github.com/python/typing/commit/2acaa5acd01aeabb295e961913c111a7df52656d"><code>2acaa5a</code></a> test that all names are present in <strong>all</strong> (<a href="https://github-redirect.dependabot.com/python/typing/issues/1138">#1138</a>)</li>
<li><a href="https://github.com/python/typing/commit/e7bc381dc7a4dbc94441759af31f576bbd7302c6"><code>e7bc381</code></a> Add <code>assert_type</code> to <code>__all__</code> (<a href="https://github-redirect.dependabot.com/python/typing/issues/1136">#1136</a>)</li>
<li><a href="https://github.com/python/typing/commit/cba3a90903fd19a33ef65784744f164e9582b7ee"><code>cba3a90</code></a> Fix &quot;accepts only single type&quot; errors (<a href="https://github-redirect.dependabot.com/python/typing/issues/1130">#1130</a>)</li>
<li><a href="https://github.com/python/typing/commit/db20497ae1be03d89e9cd083aa93cdff9c786831"><code>db20497</code></a> Add assert_type (<a href="https://github-redirect.dependabot.com/python/typing/issues/1103">#1103</a>)</li>
<li><a href="https://github.com/python/typing/commit/07fb800b29127a46a9c422d4dbc4e4d96df69d3f"><code>07fb800</code></a> LiteralString, NotRequired, Required will be in 3.11 (<a href="https://github-redirect.dependabot.com/python/typing/issues/1110">#1110</a>)</li>
<li>Additional commits viewable in <a href="https://github.com/python/typing/compare/4.1.1...4.2.0">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=typing-extensions&package-manager=pip&previous-version=4.1.1&new-version=4.2.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>


Patch:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 08b22ce39..607016890 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -246,9 +246,6 @@ jobs:
       with:
         python-version: '3.10'
 
-    - name: upgrade pip
-      run: pip install -U pip setuptools wheel
-
     - name: install
       run: make install-testing
 
diff --git a/changes/3641-PrettyWood.md b/changes/3641-PrettyWood.md
new file mode 100644
index 000000000..d0338c663
--- /dev/null
+++ b/changes/3641-PrettyWood.md
@@ -0,0 +1,1 @@
+`Config.copy_on_model_validation` does a deep copy and not a shallow one
\ No newline at end of file
diff --git a/pydantic/main.py b/pydantic/main.py
index eea8abcbb..1dcda9efd 100644
--- a/pydantic/main.py
+++ b/pydantic/main.py
@@ -666,7 +666,7 @@ class BaseModel(Representation, metaclass=ModelMetaclass):
     def validate(cls: Type['Model'], value: Any) -> 'Model':
         if isinstance(value, cls):
             if cls.__config__.copy_on_model_validation:
-                return value._copy_and_set_values(value.__dict__, value.__fields_set__, deep=False)
+                return value._copy_and_set_values(value.__dict__, value.__fields_set__, deep=True)
             else:
                 return value
 
diff --git a/requirements.txt b/requirements.txt
index 3beeb0fdb..71a0fbf00 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -4,5 +4,5 @@ Cython==0.29.28;sys_platform!='win32'
 devtools==0.8.0
 email-validator==1.1.3
 dataclasses==0.6; python_version < '3.7'
-typing-extensions==4.1.1
+typing-extensions==4.2.0
 python-dotenv==0.20.0


Test patch:
diff --git a/tests/test_main.py b/tests/test_main.py
index c00d70688..f4d3844c4 100644
--- a/tests/test_main.py
+++ b/tests/test_main.py
@@ -1561,12 +1561,28 @@ def test_model_exclude_copy_on_model_validation():
 
     assert t.user is not my_user
     assert t.user.hobbies == ['scuba diving']
-    assert t.user.hobbies is my_user.hobbies  # `Config.copy_on_model_validation` only does a shallow copy
+    assert t.user.hobbies is not my_user.hobbies  # `Config.copy_on_model_validation` does a deep copy
     assert t.user._priv == 13
     assert t.user.password.get_secret_value() == 'hashedpassword'
     assert t.dict() == {'id': '1234567890', 'user': {'id': 42, 'hobbies': ['scuba diving']}}
 
 
+def test_validation_deep_copy():
+    """By default, Config.copy_on_model_validation should do a deep copy"""
+
+    class A(BaseModel):
+        name: str
+
+    class B(BaseModel):
+        list_a: List[A]
+
+    a = A(name='a')
+    b = B(list_a=[a])
+    assert b.list_a == [A(name='a')]
+    a.name = 'b'
+    assert b.list_a == [A(name='a')]
+
+
 @pytest.mark.parametrize(
     'kinds',
     [