Instances share objects after copy or created from unpacking a dict
See original GitHub issueThis is related to #154 and I’m using pydantic v0.12.1
Here is a simple example to show what I mean.
>>> class Model(pydantic.BaseModel):
... my_dict: dict
...
>>> model1 = Model(**{'my_dict': {'my_list': [1,2,3]}})
>>> model1
<Model my_dict={'my_list': [1, 2, 3]}>
>>> model2 = model1.copy()
>>> model2
<Model my_dict={'my_list': [1, 2, 3]}>
>>> model2.my_dict['my_list'] = []
>>> model2
<Model my_dict={'my_list': []}>
>>> model1
<Model my_dict={'my_list': []}>
Another example when created by unpacking a dictionary.
>>> my_dict = {'my_dict': {'my_list': [1,2,3]}}
>>> model1 = Model(**my_dict)
>>> model1
<Model my_dict={'my_list': [1, 2, 3]}>
>>> model2 = Model(**my_dict)
>>> model2
<Model my_dict={'my_list': [1, 2, 3]}>
>>> model2.my_dict['my_list'] = []
>>> model1
<Model my_dict={'my_list': []}>
>>> model2
<Model my_dict={'my_list': []}>
BaseModel.dict() seems to create copies correctly and can be used instead of .copy() to create a new object as seen with model3 in this example.
>>> model1 = Model(**{'my_dict': {'my_list': [1,2,3]}})
>>> model1
<Model my_dict={'my_list': [1, 2, 3]}>
>>> model2 = model1.copy()
>>> model2
<Model my_dict={'my_list': [1, 2, 3]}>
>>> model3 = Model(**model1.dict())
>>> model3
<Model my_dict={'my_list': [1, 2, 3]}>
>>> model2.my_dict['my_list'] = []
>>> model1
<Model my_dict={'my_list': []}>
>>> model2
<Model my_dict={'my_list': []}>
>>> model3
<Model my_dict={'my_list': [1, 2, 3]}>
I think this is quite serious since you can’t know if you are working with a true copy of a model or not.
I see two things that need to be fixed.
.copy() should create a deepcopy that doesn’t share any objects with the model it was copied from. User created classes have to support deepcopy operations to work correctly.
BaseModel(**dict) need to make sure that all items in the dict are deepcopied from the unpacked dictionary.
Issue Analytics
- State:
- Created 5 years ago
- Comments:7 (7 by maintainers)
Top Results From Across the Web
Instances share objects after copy or created from unpacking ...
I see two things that need to be fixed. .copy() should create a deepcopy that doesn't share any objects with the model it...
Read more >"unpacking" a passed dictionary into the function's name ...
It doesn't exactly bring dictionary contents into the local namespace, but comes close if you use short names for the objects. Share.
Read more >Shallow and deep copy in Python: copy(), deepcopy()
To create a copy instead of a reference of the same object, use the copy() method or the copy.deepcopy() function described below. On...
Read more >5 Ways to Merge Dictionaries in Python | by Jimit Dholakia
Method 2: Using the unpacking operator We can merge dictionaries in one line by simply using the unpacking operator (**). We can also...
Read more >collections — Container datatypes — Python 3.11.1 ...
This module implements specialized container datatypes providing alternatives to Python's general purpose built-in containers, dict , list , set , and tuple ....
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
BTW, you can reference other issues with
#<issue number>
you don’t have to create a markdown link to the issue, this also has the advantage of showing the reference on the referenced issue.Took a little longer than expected before I had time to do this, but now it’s done.