Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Config.copy_on_model_validation does a deep copy and not a shallow one #3642

Merged
merged 5 commits into from May 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 0 additions & 3 deletions .github/workflows/ci.yml
Expand Up @@ -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

Expand Down
1 change: 1 addition & 0 deletions changes/3641-PrettyWood.md
@@ -0,0 +1 @@
`Config.copy_on_model_validation` does a deep copy and not a shallow one
2 changes: 1 addition & 1 deletion pydantic/main.py
Expand Up @@ -666,7 +666,7 @@ def __get_validators__(cls) -> 'CallableGenerator':
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

Expand Down
18 changes: 17 additions & 1 deletion tests/test_main.py
Expand Up @@ -1561,12 +1561,28 @@ class Config:

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',
[
Expand Down