diff --git a/.github/workflows/ci-additional.yaml b/.github/workflows/ci-additional.yaml index 91c63528741..84114056312 100644 --- a/.github/workflows/ci-additional.yaml +++ b/.github/workflows/ci-additional.yaml @@ -123,7 +123,7 @@ jobs: python -m mypy --install-types --non-interactive --cobertura-xml-report mypy_report - name: Upload mypy coverage to Codecov - uses: codecov/codecov-action@v5.0.7 + uses: codecov/codecov-action@v5.1.1 with: file: mypy_report/cobertura.xml flags: mypy @@ -174,7 +174,7 @@ jobs: python -m mypy --install-types --non-interactive --cobertura-xml-report mypy_report - name: Upload mypy coverage to Codecov - uses: codecov/codecov-action@v5.0.7 + uses: codecov/codecov-action@v5.1.1 with: file: mypy_report/cobertura.xml flags: mypy-min @@ -230,7 +230,7 @@ jobs: python -m pyright xarray/ - name: Upload pyright coverage to Codecov - uses: codecov/codecov-action@v5.0.7 + uses: codecov/codecov-action@v5.1.1 with: file: pyright_report/cobertura.xml flags: pyright @@ -286,7 +286,7 @@ jobs: python -m pyright xarray/ - name: Upload pyright coverage to Codecov - uses: codecov/codecov-action@v5.0.7 + uses: codecov/codecov-action@v5.1.1 with: file: pyright_report/cobertura.xml flags: pyright39 diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index b0996acf6fe..ad710e36247 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -159,7 +159,9 @@ jobs: path: pytest.xml - name: Upload code coverage to Codecov - uses: codecov/codecov-action@v5.0.7 + uses: codecov/codecov-action@v5.1.1 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: file: ./coverage.xml flags: unittests diff --git a/.github/workflows/upstream-dev-ci.yaml b/.github/workflows/upstream-dev-ci.yaml index 30047673187..6a8b8d777c4 100644 --- a/.github/workflows/upstream-dev-ci.yaml +++ b/.github/workflows/upstream-dev-ci.yaml @@ -140,7 +140,7 @@ jobs: run: | python -m mypy --install-types --non-interactive --cobertura-xml-report mypy_report - name: Upload mypy coverage to Codecov - uses: codecov/codecov-action@v5.0.7 + uses: codecov/codecov-action@v5.1.1 with: file: mypy_report/cobertura.xml flags: mypy diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 9a8154d3791..6a08246182c 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -14,9 +14,9 @@ What's New np.random.seed(123456) -.. _whats-new.2024.11.1: +.. _whats-new.2024.12.0: -v.2024.11.1 (unreleased) +v.2024.12.0 (unreleased) ------------------------ New Features @@ -28,7 +28,12 @@ New Features Breaking changes ~~~~~~~~~~~~~~~~ - +- Methods including ``dropna``, ``rank``, ``idxmax``, ``idxmin`` require + non-dimension arguments to be passed as keyword arguments. The previous + behavior, which allowed ``.idxmax('foo', 'all')`` was too easily confused with + ``'all'`` being a dimension. The updated equivalent is ``.idxmax('foo', + how='all')``. The previous behavior was deprecated in v2023.10.0. + By `Maximilian Roos `_. Deprecations ~~~~~~~~~~~~ diff --git a/xarray/backends/zarr.py b/xarray/backends/zarr.py index 3124cf62769..231834ec1ba 100644 --- a/xarray/backends/zarr.py +++ b/xarray/backends/zarr.py @@ -634,7 +634,7 @@ def open_store( zarr_format=None, use_zarr_fill_value_as_mask=None, write_empty: bool | None = None, - cache_array_keys: bool = True, + cache_array_keys: bool = False, ): ( zarr_group, diff --git a/xarray/core/dataarray.py b/xarray/core/dataarray.py index 5150998aebb..d287564cfe5 100644 --- a/xarray/core/dataarray.py +++ b/xarray/core/dataarray.py @@ -1026,7 +1026,6 @@ def reset_coords( drop: Literal[True], ) -> Self: ... - @_deprecate_positional_args("v2023.10.0") def reset_coords( self, names: Dims = None, @@ -1364,7 +1363,6 @@ def chunksizes(self) -> Mapping[Any, tuple[int, ...]]: all_variables = [self.variable] + [c.variable for c in self.coords.values()] return get_chunksizes(all_variables) - @_deprecate_positional_args("v2023.10.0") def chunk( self, chunks: T_ChunksFreq = {}, # noqa: B006 # {} even though it's technically unsafe, is being used intentionally here (#4667) @@ -1835,7 +1833,6 @@ def thin( ds = self._to_temp_dataset().thin(indexers, **indexers_kwargs) return self._from_temp_dataset(ds) - @_deprecate_positional_args("v2023.10.0") def broadcast_like( self, other: T_DataArrayOrSet, @@ -1948,7 +1945,6 @@ def _reindex_callback( return da - @_deprecate_positional_args("v2023.10.0") def reindex_like( self, other: T_DataArrayOrSet, @@ -2135,7 +2131,6 @@ def reindex_like( fill_value=fill_value, ) - @_deprecate_positional_args("v2023.10.0") def reindex( self, indexers: Mapping[Any, Any] | None = None, @@ -2960,7 +2955,6 @@ def stack( ) return self._from_temp_dataset(ds) - @_deprecate_positional_args("v2023.10.0") def unstack( self, dim: Dims = None, @@ -3385,7 +3379,6 @@ def drop_isel( dataset = dataset.drop_isel(indexers=indexers, **indexers_kwargs) return self._from_temp_dataset(dataset) - @_deprecate_positional_args("v2023.10.0") def dropna( self, dim: Hashable, @@ -4889,7 +4882,6 @@ def _title_for_slice(self, truncate: int = 50) -> str: return title - @_deprecate_positional_args("v2023.10.0") def diff( self, dim: Hashable, @@ -5198,7 +5190,6 @@ def sortby( ds = self._to_temp_dataset().sortby(variables, ascending=ascending) return self._from_temp_dataset(ds) - @_deprecate_positional_args("v2023.10.0") def quantile( self, q: ArrayLike, @@ -5318,7 +5309,6 @@ def quantile( ) return self._from_temp_dataset(ds) - @_deprecate_positional_args("v2023.10.0") def rank( self, dim: Hashable, @@ -5897,7 +5887,6 @@ def pad( ) return self._from_temp_dataset(ds) - @_deprecate_positional_args("v2023.10.0") def idxmin( self, dim: Hashable | None = None, @@ -5995,7 +5984,6 @@ def idxmin( keep_attrs=keep_attrs, ) - @_deprecate_positional_args("v2023.10.0") def idxmax( self, dim: Hashable = None, @@ -6093,7 +6081,6 @@ def idxmax( keep_attrs=keep_attrs, ) - @_deprecate_positional_args("v2023.10.0") def argmin( self, dim: Dims = None, @@ -6195,7 +6182,6 @@ def argmin( else: return self._replace_maybe_drop_dims(result) - @_deprecate_positional_args("v2023.10.0") def argmax( self, dim: Dims = None, @@ -6544,7 +6530,6 @@ def curvefit( kwargs=kwargs, ) - @_deprecate_positional_args("v2023.10.0") def drop_duplicates( self, dim: Hashable | Iterable[Hashable], diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index 2c1f5cfd4ac..ea17a69f827 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -3276,9 +3276,11 @@ def _shuffle(self, dim, *, indices: GroupIndices, chunks: T_Chunks) -> Self: subset = self[[name for name in self._variables if name not in is_chunked]] no_slices: list[list[int]] = [ - list(range(*idx.indices(self.sizes[dim]))) - if isinstance(idx, slice) - else idx + ( + list(range(*idx.indices(self.sizes[dim]))) + if isinstance(idx, slice) + else idx + ) for idx in indices ] no_slices = [idx for idx in no_slices if idx] @@ -5102,7 +5104,6 @@ def set_index( variables, coord_names=coord_names, indexes=indexes_ ) - @_deprecate_positional_args("v2023.10.0") def reset_index( self, dims_or_levels: Hashable | Sequence[Hashable], @@ -5740,7 +5741,6 @@ def _unstack_full_reindex( variables, coord_names=coord_names, indexes=indexes ) - @_deprecate_positional_args("v2023.10.0") def unstack( self, dim: Dims = None, @@ -6502,7 +6502,6 @@ def transpose( ds._variables[name] = var.transpose(*var_dims) return ds - @_deprecate_positional_args("v2023.10.0") def dropna( self, dim: Hashable, @@ -7976,7 +7975,6 @@ def _copy_attrs_from(self, other): if v in self.variables: self.variables[v].attrs = other.variables[v].attrs - @_deprecate_positional_args("v2023.10.0") def diff( self, dim: Hashable, @@ -8324,7 +8322,6 @@ def sortby( indices[key] = order if ascending else order[::-1] return aligned_self.isel(indices) - @_deprecate_positional_args("v2023.10.0") def quantile( self, q: ArrayLike, @@ -8505,7 +8502,6 @@ def quantile( ) return new.assign_coords(quantile=q) - @_deprecate_positional_args("v2023.10.0") def rank( self, dim: Hashable, @@ -9476,7 +9472,6 @@ def pad( attrs = self._attrs if keep_attrs else None return self._replace_with_new_dims(variables, indexes=indexes, attrs=attrs) - @_deprecate_positional_args("v2023.10.0") def idxmin( self, dim: Hashable | None = None, @@ -9575,7 +9570,6 @@ def idxmin( ) ) - @_deprecate_positional_args("v2023.10.0") def idxmax( self, dim: Hashable | None = None, @@ -10258,7 +10252,6 @@ def _wrapper(Y, *args, **kwargs): return result - @_deprecate_positional_args("v2023.10.0") def drop_duplicates( self, dim: Hashable | Iterable[Hashable], diff --git a/xarray/core/groupby.py b/xarray/core/groupby.py index 9596d19e735..ceae79031f8 100644 --- a/xarray/core/groupby.py +++ b/xarray/core/groupby.py @@ -50,7 +50,6 @@ ) from xarray.core.variable import IndexVariable, Variable from xarray.namedarray.pycompat import is_chunked_array -from xarray.util.deprecation_helpers import _deprecate_positional_args if TYPE_CHECKING: from numpy.typing import ArrayLike @@ -1183,7 +1182,6 @@ def fillna(self, value: Any) -> T_Xarray: """ return ops.fillna(self, value) - @_deprecate_positional_args("v2023.10.0") def quantile( self, q: ArrayLike, diff --git a/xarray/core/weighted.py b/xarray/core/weighted.py index 2c6e7d4282a..269cb49a2c1 100644 --- a/xarray/core/weighted.py +++ b/xarray/core/weighted.py @@ -11,7 +11,6 @@ from xarray.core.computation import apply_ufunc, dot from xarray.core.types import Dims, T_DataArray, T_Xarray from xarray.namedarray.utils import is_duck_dask_array -from xarray.util.deprecation_helpers import _deprecate_positional_args # Weighted quantile methods are a subset of the numpy supported quantile methods. QUANTILE_METHODS = Literal[ @@ -454,7 +453,6 @@ def _weighted_quantile_1d( def _implementation(self, func, dim, **kwargs): raise NotImplementedError("Use `Dataset.weighted` or `DataArray.weighted`") - @_deprecate_positional_args("v2023.10.0") def sum_of_weights( self, dim: Dims = None, @@ -465,7 +463,6 @@ def sum_of_weights( self._sum_of_weights, dim=dim, keep_attrs=keep_attrs ) - @_deprecate_positional_args("v2023.10.0") def sum_of_squares( self, dim: Dims = None, @@ -477,7 +474,6 @@ def sum_of_squares( self._sum_of_squares, dim=dim, skipna=skipna, keep_attrs=keep_attrs ) - @_deprecate_positional_args("v2023.10.0") def sum( self, dim: Dims = None, @@ -489,7 +485,6 @@ def sum( self._weighted_sum, dim=dim, skipna=skipna, keep_attrs=keep_attrs ) - @_deprecate_positional_args("v2023.10.0") def mean( self, dim: Dims = None, @@ -501,7 +496,6 @@ def mean( self._weighted_mean, dim=dim, skipna=skipna, keep_attrs=keep_attrs ) - @_deprecate_positional_args("v2023.10.0") def var( self, dim: Dims = None, @@ -513,7 +507,6 @@ def var( self._weighted_var, dim=dim, skipna=skipna, keep_attrs=keep_attrs ) - @_deprecate_positional_args("v2023.10.0") def std( self, dim: Dims = None, diff --git a/xarray/tests/test_backends.py b/xarray/tests/test_backends.py index f05a53ed2da..6e5d7170553 100644 --- a/xarray/tests/test_backends.py +++ b/xarray/tests/test_backends.py @@ -409,12 +409,8 @@ def test_zero_dimensional_variable(self) -> None: def test_write_store(self) -> None: expected = create_test_data() - with self.create_store() as store: - expected.dump_to_store(store) - # we need to cf decode the store because it has time and - # non-dimension coordinates - with xr.decode_cf(store) as actual: - assert_allclose(expected, actual) + with self.roundtrip(expected) as actual: + assert_identical(actual, expected) def check_dtypes_roundtripped(self, expected, actual): for k in expected.variables: