Skip to content

Commit

Permalink
fix: Config.copy_on_model_validation does a deep copy and not a sha…
Browse files Browse the repository at this point in the history
…llow one

closes pydantic#3641
  • Loading branch information
PrettyWood committed Jan 9, 2022
1 parent fbf8002 commit ae40832
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 2 deletions.
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

0 comments on commit ae40832

Please sign in to comment.