Skip to content

Commit d73c212

Browse files
kkollsgaclaude
andcommitted
Raise TypeError when Dataset passed as data_vars to Dataset constructor
Dataset(ds) silently dropped attrs because Dataset inherits from Mapping, so the constructor iterated over data variable keys while ignoring attrs. This was never intended behavior. Raise TypeError with a message directing users to ds.copy() instead. Closes GH11095 Co-authored-by: Claude <noreply@anthropic.com>
1 parent d68c013 commit d73c212

File tree

3 files changed

+18
-0
lines changed

3 files changed

+18
-0
lines changed

doc/whats-new.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ New Features
1818
Breaking Changes
1919
~~~~~~~~~~~~~~~~
2020

21+
- Passing a :py:class:`Dataset` as ``data_vars`` to the :py:class:`Dataset`
22+
constructor now raises :py:class:`TypeError`. This was never intended behavior
23+
and silently dropped ``attrs``. Use :py:meth:`Dataset.copy` instead
24+
(:issue:`11095`).
25+
By `Kristian Kollsga <https://github.com/kkollsga>`_.
2126

2227
Deprecations
2328
~~~~~~~~~~~~

xarray/core/dataset.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,11 @@ def __init__(
385385
) -> None:
386386
if data_vars is None:
387387
data_vars = {}
388+
if isinstance(data_vars, Dataset):
389+
raise TypeError(
390+
"Passing a Dataset as `data_vars` to the Dataset constructor is"
391+
" not supported. Use `ds.copy()` to create a copy of a Dataset."
392+
)
388393
if coords is None:
389394
coords = {}
390395

xarray/tests/test_dataset.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,14 @@ def test_constructor(self) -> None:
494494
actual = Dataset({"z": expected["z"]})
495495
assert_identical(expected, actual)
496496

497+
def test_constructor_dataset_as_data_vars_raises(self) -> None:
498+
ds = Dataset({"x": ("x", [1, 2, 3])}, attrs={"key": "value"})
499+
with pytest.raises(
500+
TypeError,
501+
match=r"Passing a Dataset as `data_vars`.*Use `ds\.copy\(\)`",
502+
):
503+
Dataset(ds)
504+
497505
def test_constructor_1d(self) -> None:
498506
expected = Dataset({"x": (["x"], 5.0 + np.arange(5))})
499507
actual = Dataset({"x": 5.0 + np.arange(5)})

0 commit comments

Comments
 (0)