Skip to content

Complete deprecation of Dataset.dims returning dict #8980

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/whats-new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ Breaking changes
zarr 2.13 2.14
===================== ========= =======

- Changed the return type of :py:meth:`Dataset.dims` and :py:meth:`DatasetGroupBy.dims` to a frozen set,
completing the deprecation cycle started in :pull:`8500`. (:pull:`8980`)
By `Tom Nicholas <https://github.com/TomNicholas>`_.

Bug fixes
~~~~~~~~~
Expand Down
12 changes: 3 additions & 9 deletions xarray/core/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@
from xarray.core.utils import (
Default,
Frozen,
FrozenMappingWarningOnValuesAccess,
HybridMappingProxy,
OrderedSet,
_default,
Expand Down Expand Up @@ -766,22 +765,17 @@ def drop_encoding(self) -> Self:
return self._replace(variables=variables, encoding={})

@property
def dims(self) -> Frozen[Hashable, int]:
"""Mapping from dimension names to lengths.
def dims(self) -> frozenset[Hashable]:
"""Set of dimension names.

Cannot be modified directly, but is updated when adding new variables.

Note that type of this object differs from `DataArray.dims`.
See `Dataset.sizes` and `DataArray.sizes` for consistently named
properties. This property will be changed to return a type more consistent with
`DataArray.dims` in the future, i.e. a set of dimension names.

See Also
--------
Dataset.sizes
DataArray.dims
"""
return FrozenMappingWarningOnValuesAccess(self._dims)
return frozenset(self._dims.keys())

@property
def sizes(self) -> Frozen[Hashable, int]:
Expand Down
16 changes: 13 additions & 3 deletions xarray/core/groupby.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
T_Xarray,
)
from xarray.core.utils import (
FrozenMappingWarningOnValuesAccess,
contains_only_chunked_or_numpy,
either_dict_or_kwargs,
emit_user_level_warning,
Expand Down Expand Up @@ -1775,7 +1774,18 @@ class DatasetGroupByBase(GroupBy["Dataset"], DatasetGroupbyArithmetic):
_dims: Frozen[Hashable, int] | None

@property
def dims(self) -> Frozen[Hashable, int]:
def dims(self) -> frozenset[Hashable]:
"""Set of dimension names.

Immutable.

See Also
--------
DataArray.dims
DataArray.sizes
Dataset.sizes
"""

if self._dims is None:
(grouper,) = self.groupers
index = _maybe_squeeze_indices(
Expand All @@ -1786,7 +1796,7 @@ def dims(self) -> Frozen[Hashable, int]:
)
self._dims = self._obj.isel({self._group_dim: index}).dims

return FrozenMappingWarningOnValuesAccess(self._dims)
return frozenset(self._dims.keys())

def map(
self,
Expand Down
52 changes: 0 additions & 52 deletions xarray/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,11 @@
Collection,
Container,
Hashable,
ItemsView,
Iterable,
Iterator,
KeysView,
Mapping,
MutableMapping,
MutableSet,
ValuesView,
)
from enum import Enum
from pathlib import Path
Expand Down Expand Up @@ -443,55 +440,6 @@ def FrozenDict(*args, **kwargs) -> Frozen:
return Frozen(dict(*args, **kwargs))


class FrozenMappingWarningOnValuesAccess(Frozen[K, V]):
"""
Class which behaves like a Mapping but warns if the values are accessed.

Temporary object to aid in deprecation cycle of `Dataset.dims` (see GH issue #8496).
`Dataset.dims` is being changed from returning a mapping of dimension names to lengths to just
returning a frozen set of dimension names (to increase consistency with `DataArray.dims`).
This class retains backwards compatibility but raises a warning only if the return value
of ds.dims is used like a dictionary (i.e. it doesn't raise a warning if used in a way that
would also be valid for a FrozenSet, e.g. iteration).
"""

__slots__ = ("mapping",)

def _warn(self) -> None:
emit_user_level_warning(
"The return type of `Dataset.dims` will be changed to return a set of dimension names in future, "
"in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, "
"please use `Dataset.sizes`.",
FutureWarning,
)

def __getitem__(self, key: K) -> V:
self._warn()
return super().__getitem__(key)

@overload
def get(self, key: K, /) -> V | None: ...

@overload
def get(self, key: K, /, default: V | T) -> V | T: ...

def get(self, key: K, default: T | None = None) -> V | T | None:
self._warn()
return super().get(key, default)

def keys(self) -> KeysView[K]:
self._warn()
return super().keys()

def items(self) -> ItemsView[K, V]:
self._warn()
return super().items()

def values(self) -> ValuesView[V]:
self._warn()
return super().values()


class HybridMappingProxy(Mapping[K, V]):
"""Implements the Mapping interface. Uses the wrapped mapping for item lookup
and a separate wrapped keys collection for iteration.
Expand Down
Loading