Skip to content

Using Dataset Constructor to create a copy drops attrs #11095

@Reshief

Description

@Reshief

What happened?

I encountered an unexpected behavior while using xarray, which I would consider to be a bug.
Similar to other types/classes, I attempted to create a copy of a dataset by using the constructor of the xarray.Dataset class.
For some time, I did not notice any issues, but just today I realized that this creates a new dataset that holds all relevant information except for the .attrs of the dataset.
Specifically, I checked that the new dataset copies over the data vars from the provided dataset and reconstructs the coordinates, but completely loses the attributes.

I am using xarray version "2025.12.0" for my tests, but the relevant code in the __init__() function of xarray.Dataset at [datataset.py:lines 378-410](https://github.com/pydata/xarray/blob/main/xarray/core/dataset.py) has not changed.

Looking at the code in the constructor, the first argument to the constructor is used as a source for variables in the new dataset and then the list of coordinates is reconstructed.
There is a special treatment for the coord parameter being a Dataset, but not for the data_vars parameter.

What did you expect to happen?

Given that the constructor for all my intents and purposes creates a shallow copy of the Dataset, I expected it to create a copy of the attributes as well.
I am aware of the .copy() function, but I would expect the call to xr.Dataset(ds) to effectively work as a copy instructor thus copying the attributes from the input as well, to fail the initialization or to output a warning that the result may be unexpected.

Minimal Complete Verifiable Example

# /// script
# requires-python = ">=3.11"
# dependencies = [
#   "xarray[complete]@git+https://github.com/pydata/xarray.git@main",
# ]
# ///
#
# This script automatically imports the development branch of xarray to check for issues.
# Please delete this header if you have _not_ tested this script with `uv run`!

import xarray as xr
xr.show_versions()

# your reproducer code ...import xarray as xr

ds = xr.Dataset()
ds.attrs['magic_key'] = True

assert 'magic_key' in ds.attrs # This is successful

# Create a copy:
ds2 = xr.Dataset(ds)
assert 'magic_key' in ds2.attrs # This is unsuccessful, the attrs are completely empty

Steps to reproduce

  1. Create a dataset ds = xr.Dataset()
  2. Set an attribute on the dataset ds.attrs['magic_key']=True
  3. Create a new dataset from the old dataset ds2 = xr.Dataset(ds)
  4. The new dataset has lost all attributes.

MVCE confirmation

  • Minimal example — the example is as focused as reasonably possible to demonstrate the underlying issue in xarray.
  • Complete example — the example is self-contained, including all data and the text of any traceback.
  • Verifiable example — the example copy & pastes into an IPython prompt or Binder notebook, returning the result.
  • New issue — a search of GitHub Issues suggests this is not a duplicate.
  • Recent environment — the issue occurs with the latest version of xarray and its dependencies.

Relevant log output

Anything else we need to know?

I would suggest a change to the constructor that it can effectively be used as a shallow copy of the dataset, e.g. such that it can used in copy operations of the form type(ds)(ds) similar to other datatypes.

For this, a simple change to line 398 in my version or line 404 in the current (at time of writing) commit to the main branch of the constructor would suffice:
self._attrs = dict(attrs) if attrs else None
could be replaced by
self._attrs = dict(attrs) if attrs else dict(data_vars.attrs) if isinstance(data_vars, Dataset) else None

If there is a reason for why the constructor should not be able to operate similar to a copy constructor, I would suggest adding a warning if a dataset is supplied with some attributes in ds.attrs set and no attrs parameter being provided because the current behavior may be unexpected.

Environment

Details INSTALLED VERSIONS ------------------ commit: None python: 3.12.2 (tags/v3.12.2:6abddd9, Feb 6 2024, 21:26:36) [MSC v.1937 64 bit (AMD64)] python-bits: 64 OS: Windows OS-release: 10 machine: AMD64 processor: AMD64 Family 25 Model 33 Stepping 2, AuthenticAMD byteorder: little LC_ALL: None LANG: None LOCALE: ('de_DE', 'cp1252') libhdf5: 1.14.6 libnetcdf: None

xarray: 2025.12.0
pandas: 2.3.3
numpy: 2.3.5
scipy: 1.16.3
netCDF4: None
pydap: None
h5netcdf: 1.7.3
h5py: 3.15.1
zarr: None
cftime: None
nc_time_axis: None
iris: None
bottleneck: None
dask: None
distributed: None
matplotlib: 3.10.8
cartopy: None
seaborn: 0.13.2
numbagg: None
fsspec: 2025.12.0
cupy: None
pint: None
sparse: None
flox: None
numpy_groupies: None
setuptools: 80.9.0
pip: 25.3
conda: None
pytest: 9.0.2
mypy: 1.18.2
IPython: 9.8.0
sphinx: 8.2.3

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions