model.deepcopy() does not do a deep copy
See original GitHub issueDescription
A deep copy should lose any link to the original object, so that one can modify the copy with no side effects on the original object. In a Jupyter notebook, something happens that makes this fail.
Expected behavior
I would expect that a deepcopy would allow to modify the copy without any change happening to the original model.
Actual behavior
The original model gets changed when I change the parameters of the new model in place (e.g. with _fitter_to_model_params). It turns out that, when I run the method in a Jupyter notebook, the parameter array in the copied version is not a deepcopy, but a reference to the original parameter array, as demonstrated below. I couldn’t reproduce this by adding the lines below to the existing unit tests
Steps to Reproduce
# define power law component
pl = models.PowerLaw1D()
pl2 = pl.deepcopy()
id(pl) != id(pl2) #---> True
id(pl.parameters) != id(pl2.parameters) #--> False!!
System Details
macOS-10.16-x86_64-i386-64bit Python 3.8.8 (default, Feb 24 2021, 13:46:16) [Clang 10.0.0 ] Numpy 1.20.1 astropy 4.2 and 4.3.dev754+gba283e72d Scipy 1.6.1 Matplotlib 3.3.4
Issue Analytics
- State:
- Created 2 years ago
- Comments:8 (8 by maintainers)
Top GitHub Comments
If we documented it for this case, there are many other cases where it would need to be documented to be consistent. That seems like a rather large job. It is essentially true for any computed property (though most properties are not computed).
I think we tracked it down. It really isn’t a bug, but it sure is an unexpected behavior. The parameters attribute is actually a property, and the resulting array is regenerated every time that attribute is accessed. Apparently what is going on is that the first id() call returns a result (the memory address of the array), that result is stored in a temporary location, and the array memory is released immediately. The second id() call results in the reuse of the same memory location (which apparently doesn’t happen when I call them on separate lines), and thus the same id value, confusing all of us.
The moral is: don’t trust the identity of properties.