diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 6cf2720a033..48323ee629c 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -25,10 +25,11 @@ Enhancements Bug fixes ~~~~~~~~~ +- Dataset.copy(deep=True) now creates a deep copy of the attrs (:issue:`2835`). + By `Andras Gefferth `_. - ``swap_dims`` would create incorrect ``indexes`` (:issue:`2842`). By `Stephan Hoyer `_. - .. _whats-new.0.12.0: v0.12.0 (15 March 2019) diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index 3bb54e80456..4ee70002102 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -915,7 +915,9 @@ def copy(self: T, deep: bool = False, data: Mapping = None) -> T: variables = OrderedDict((k, v.copy(deep=deep, data=data.get(k))) for k, v in self._variables.items()) - return self._replace(variables) + attrs = copy.deepcopy(self._attrs) if deep else copy.copy(self._attrs) + + return self._replace(variables, attrs=attrs) @property def _level_coords(self): diff --git a/xarray/tests/test_dataset.py b/xarray/tests/test_dataset.py index 777a8e84a3f..ad59cede5f4 100644 --- a/xarray/tests/test_dataset.py +++ b/xarray/tests/test_dataset.py @@ -1885,6 +1885,7 @@ def test_drop_dims(self): def test_copy(self): data = create_test_data() + data.attrs['Test'] = [1, 2, 3] for copied in [data.copy(deep=False), copy(data)]: assert_identical(data, copied) @@ -1899,12 +1900,18 @@ def test_copy(self): copied['foo'] = ('z', np.arange(5)) assert 'foo' not in data + copied.attrs['foo'] = 'bar' + assert 'foo' not in data.attrs + assert data.attrs['Test'] is copied.attrs['Test'] + for copied in [data.copy(deep=True), deepcopy(data)]: assert_identical(data, copied) for k, v0 in data.variables.items(): v1 = copied.variables[k] assert v0 is not v1 + assert data.attrs['Test'] is not copied.attrs['Test'] + def test_copy_with_data(self): orig = create_test_data() new_data = {k: np.random.randn(*v.shape)