question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Instances share objects after copy or created from unpacking a dict

See original GitHub issue

This 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:closed
  • Created 5 years ago
  • Comments:7 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
samuelcolvincommented, Aug 25, 2018

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.

0reactions
gangeforscommented, Sep 10, 2018

Took a little longer than expected before I had time to do this, but now it’s done.

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found