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

build(deps): bump actions/upload-artifact from 2 to 3
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 2 to 3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/actions/upload-artifact/releases">actions/upload-artifact's releases</a>.</em></p>
<blockquote>
<h2>v3.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update default runtime to node16 (<a href="https://github-redirect.dependabot.com/actions/upload-artifact/issues/293">#293</a>)</li>
<li>Update package-lock.json file version to 2 (<a href="https://github-redirect.dependabot.com/actions/upload-artifact/issues/302">#302</a>)</li>
</ul>
<h3>Breaking Changes</h3>
<p>With the update to Node 16, all scripts will now be run with Node 16 rather than Node 12.</p>
<h2>v2.3.1</h2>
<p>Fix for empty fails on Windows failing on upload <a href="https://github-redirect.dependabot.com/actions/upload-artifact/issues/281">#281</a></p>
<h2>v2.3.0 Upload Artifact</h2>
<ul>
<li>Optimizations for faster uploads of larger files that are already compressed</li>
<li>Significantly improved logging when there are chunked uploads</li>
<li>Clarifications in logs around the upload size and prohibited characters that aren't allowed in the artifact name or any uploaded files</li>
<li>Various other small bugfixes &amp; optimizations</li>
</ul>
<h2>v2.2.4</h2>
<ul>
<li>Retry on HTTP 500 responses from the service</li>
</ul>
<h2>v2.2.3</h2>
<ul>
<li>Fixes for proxy related issues</li>
</ul>
<h2>v2.2.2</h2>
<ul>
<li>Improved retryability and error handling</li>
</ul>
<h2>v2.2.1</h2>
<ul>
<li>Update used actions/core package to the latest version</li>
</ul>
<h2>v2.2.0</h2>
<ul>
<li>Support for artifact retention</li>
</ul>
<h2>v2.1.4</h2>
<ul>
<li>Add Third Party License Information</li>
</ul>
<h2>v2.1.3</h2>
<ul>
<li>Use updated version of the <code>@action/artifact</code> NPM package</li>
</ul>
<h2>v2.1.2</h2>
<ul>
<li>Increase upload chunk size from 4MB to 8MB</li>
<li>Detect case insensitive file uploads</li>
</ul>
<h2>v2.1.1</h2>
<ul>
<li>Fix for certain symlinks not correctly being identified as directories before starting uploads</li>
</ul>
<h2>v2.1.0</h2>
<ul>
<li>Support for uploading artifacts with multiple paths</li>
<li>Support for using exclude paths</li>
<li>Updates to dependencies</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/actions/upload-artifact/commit/6673cd052c4cd6fcf4b4e6e60ea986c889389535"><code>6673cd0</code></a> Update <code>lockfileVersion</code> in <code>package-lock.json</code> (<a href="https://github-redirect.dependabot.com/actions/upload-artifact/issues/302">#302</a>)</li>
<li><a href="https://github.com/actions/upload-artifact/commit/2244c8200304ec9588bf9399eac622d9fadc28c4"><code>2244c82</code></a> Update to node16 (<a href="https://github-redirect.dependabot.com/actions/upload-artifact/issues/293">#293</a>)</li>
<li><a href="https://github.com/actions/upload-artifact/commit/87348cee5fefa95e42e9b4804b4d68e130304158"><code>87348ce</code></a> Add 503 warning when uploading to the same artifact</li>
<li>See full diff in <a href="https://github.com/actions/upload-artifact/compare/v2...v3">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/upload-artifact&package-manager=github_actions&previous-version=2&new-version=3)](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..1a785e260 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -54,7 +54,7 @@ jobs:
       run: make docs
 
     - name: Store docs site
-      uses: actions/upload-artifact@v2
+      uses: actions/upload-artifact@v3
       with:
         name: docs
         path: site
@@ -120,7 +120,7 @@ jobs:
         CONTEXT: linux-py${{ matrix.python-version }}-compiled-no-deps-no
 
     - name: store coverage files
-      uses: actions/upload-artifact@v2
+      uses: actions/upload-artifact@v3
       with:
         name: coverage
         path: coverage
@@ -159,7 +159,7 @@ jobs:
         CONTEXT: ${{ matrix.os }}-py${{ matrix.python-version }}
 
     - name: store coverage files
-      uses: actions/upload-artifact@v2
+      uses: actions/upload-artifact@v3
       with:
         name: coverage
         path: coverage
@@ -200,7 +200,7 @@ jobs:
         CONTEXT: linux-py3.10-mypy${{ matrix.mypy-version }}
 
     - name: store coverage files
-      uses: actions/upload-artifact@v2
+      uses: actions/upload-artifact@v3
       with:
         name: coverage
         path: coverage
@@ -230,7 +230,7 @@ jobs:
       - run: coverage html --show-contexts
 
       - name: Store coverage html
-        uses: actions/upload-artifact@v2
+        uses: actions/upload-artifact@v3
         with:
           name: coverage-html
           path: htmlcov
@@ -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
 
@@ -311,7 +308,7 @@ jobs:
         twine check dist/*
 
     - name: Store dist artifacts
-      uses: actions/upload-artifact@v2
+      uses: actions/upload-artifact@v3
       with:
         name: pypi_files
         path: dist
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/docs/requirements.txt b/docs/requirements.txt
index 8c28433d5..da19a20fc 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -6,7 +6,7 @@ markdown-include==0.6.0
 mdx-truly-sane-lists==1.2
 mkdocs==1.3.0
 mkdocs-exclude==1.0.2
-mkdocs-material==8.2.8
+mkdocs-material==8.2.12
 sqlalchemy
 orjson
 ujson
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/requirements-testing.txt b/tests/requirements-testing.txt
index f29e6454b..5721960d3 100644
--- a/tests/requirements-testing.txt
+++ b/tests/requirements-testing.txt
@@ -3,7 +3,7 @@ hypothesis==6.41.0
 # pin importlib-metadata as upper versions need typing-extensions to work if on python < 3.8
 importlib-metadata==3.1.0;python_version<"3.8"
 mypy==0.942
-pytest==7.1.1
+pytest==7.1.2
 pytest-cov==3.0.0
 pytest-mock==3.7.0
 pytest-sugar==0.9.4
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',
     [