Skip to content
forked from pydata/xarray

Commit 8336c53

Browse files
committed
Merge branch 'main' into pr/5950
2 parents 74064b9 + 3960ea3 commit 8336c53

32 files changed

+200
-96
lines changed

.github/workflows/ci-additional.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ jobs:
9696
python -c "import xarray"
9797
- name: Run tests
9898
run: |
99-
python -m pytest -n 4 \
99+
python -m pytest \
100100
--cov=xarray \
101101
--cov-report=xml \
102102
$PYTEST_EXTRA_FLAGS

.github/workflows/ci.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ jobs:
8787
run: |
8888
python -c "import xarray"
8989
- name: Run tests
90-
run: python -m pytest -n 4
90+
run: python -m pytest
9191
--cov=xarray
9292
--cov-report=xml
9393
--junitxml=pytest.xml

.pre-commit-config.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ repos:
3232
# - id: velin
3333
# args: ["--write", "--compact"]
3434
- repo: https://github.com/pre-commit/mirrors-mypy
35-
rev: v0.910-1
35+
rev: v0.930
3636
hooks:
3737
- id: mypy
3838
# `properies` & `asv_bench` are copied from setup.cfg.

ci/install-upstream-wheels.sh

+3-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ conda uninstall -y --force \
1414
pint \
1515
bottleneck \
1616
sparse \
17+
h5netcdf \
1718
xarray
1819
# to limit the runtime of Upstream CI
1920
python -m pip install pytest-timeout
@@ -43,4 +44,5 @@ python -m pip install \
4344
git+https://github.com/pydata/bottleneck \
4445
git+https://github.com/pydata/sparse \
4546
git+https://github.com/intake/filesystem_spec \
46-
git+https://github.com/SciTools/nc-time-axis
47+
git+https://github.com/SciTools/nc-time-axis \
48+
git+https://github.com/h5netcdf/h5netcdf

ci/requirements/environment-windows.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ dependencies:
88
# - cdms2 # Not available on Windows
99
# - cfgrib # Causes Python interpreter crash on Windows: https://github.com/pydata/xarray/pull/3340
1010
- cftime
11-
- dask-core
11+
- dask-core != 2021.12.0 # https://github.com/pydata/xarray/pull/6111, can remove on next release
1212
- distributed
1313
- fsspec!=2021.7.0
1414
- h5netcdf
1515
- h5py
1616
- hdf5
1717
- hypothesis
1818
- iris
19-
- lxml # Optional dep of pydap
19+
- lxml # Optional dep of pydap
2020
- matplotlib-base
2121
- nc-time-axis
2222
- netcdf4
@@ -42,4 +42,4 @@ dependencies:
4242
- typing_extensions
4343
- zarr
4444
- pip:
45-
- numbagg
45+
- numbagg

ci/requirements/environment.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ dependencies:
1010
- cdms2
1111
- cfgrib
1212
- cftime
13-
- dask-core
13+
- dask-core != 2021.12.0 # https://github.com/pydata/xarray/pull/6111, can remove on next release
1414
- distributed
1515
- fsspec!=2021.7.0
1616
- h5netcdf
1717
- h5py
1818
- hdf5
1919
- hypothesis
2020
- iris
21-
- lxml # Optional dep of pydap
21+
- lxml # Optional dep of pydap
2222
- matplotlib-base
2323
- nc-time-axis
2424
- netcdf4
@@ -46,4 +46,4 @@ dependencies:
4646
- typing_extensions
4747
- zarr
4848
- pip:
49-
- numbagg
49+
- numbagg

doc/whats-new.rst

+33
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,37 @@ What's New
1414
1515
np.random.seed(123456)
1616
17+
.. _whats-new.0.X.Y+1:
18+
19+
v0.21.0 (unreleased)
20+
---------------------
21+
22+
New Features
23+
~~~~~~~~~~~~
24+
25+
26+
Breaking changes
27+
~~~~~~~~~~~~~~~~
28+
29+
30+
Deprecations
31+
~~~~~~~~~~~~
32+
33+
34+
Bug fixes
35+
~~~~~~~~~
36+
37+
38+
Documentation
39+
~~~~~~~~~~~~~
40+
41+
42+
Internal Changes
43+
~~~~~~~~~~~~~~~~
44+
45+
- Replace ``distutils.version`` with ``packaging.version`` (:issue:`6092`).
46+
By `Mathias Hauser <https://github.com/mathause>`_.
47+
1748

1849
.. _whats-new.0.20.2:
1950

@@ -51,6 +82,8 @@ Bug fixes
5182
By `Sebastian Weigand <https://github.com/s-weigand>`_.
5283
- Fix a regression in the removal of duplicate backend entrypoints (:issue:`5944`, :pull:`5959`)
5384
By `Kai Mühlbauer <https://github.com/kmuehlbauer>`_.
85+
- Fix an issue that datasets from being saved when time variables with units that ``cftime`` can parse but pandas can not were present (:pull:`6049`).
86+
By `Tim Heap <https://github.com/mx-moth>`_.
5487

5588
Documentation
5689
~~~~~~~~~~~~~

setup.cfg

+2
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,8 @@ ignore_missing_imports = True
198198
ignore_missing_imports = True
199199
[mypy-h5py.*]
200200
ignore_missing_imports = True
201+
[mypy-importlib_metadata.*]
202+
ignore_missing_imports = True
201203
[mypy-iris.*]
202204
ignore_missing_imports = True
203205
[mypy-matplotlib.*]

xarray/backends/h5netcdf_.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import functools
22
import io
33
import os
4-
from distutils.version import LooseVersion
54

65
import numpy as np
6+
from packaging.version import Version
77

88
from ..core import indexing
99
from ..core.utils import (
@@ -156,16 +156,16 @@ def open(
156156

157157
kwargs = {"invalid_netcdf": invalid_netcdf}
158158
if phony_dims is not None:
159-
if LooseVersion(h5netcdf.__version__) >= LooseVersion("0.8.0"):
159+
if Version(h5netcdf.__version__) >= Version("0.8.0"):
160160
kwargs["phony_dims"] = phony_dims
161161
else:
162162
raise ValueError(
163163
"h5netcdf backend keyword argument 'phony_dims' needs "
164164
"h5netcdf >= 0.8.0."
165165
)
166-
if LooseVersion(h5netcdf.__version__) >= LooseVersion(
167-
"0.10.0"
168-
) and LooseVersion(h5netcdf.core.h5py.__version__) >= LooseVersion("3.0.0"):
166+
if Version(h5netcdf.__version__) >= Version("0.10.0") and Version(
167+
h5netcdf.core.h5py.__version__
168+
) >= Version("3.0.0"):
169169
kwargs["decode_vlen_strings"] = decode_vlen_strings
170170

171171
if lock is None:

xarray/coding/cftimeindex.py

+5-7
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@
4242
import re
4343
import warnings
4444
from datetime import timedelta
45-
from distutils.version import LooseVersion
4645
from typing import Tuple, Type
4746

4847
import numpy as np
4948
import pandas as pd
49+
from packaging.version import Version
5050

5151
from xarray.core.utils import is_scalar
5252

@@ -193,15 +193,13 @@ def f(self, min_cftime_version=min_cftime_version):
193193
if cftime is None:
194194
raise ModuleNotFoundError("No module named 'cftime'")
195195

196-
version = cftime.__version__
197-
198-
if LooseVersion(version) >= LooseVersion(min_cftime_version):
196+
if Version(cftime.__version__) >= Version(min_cftime_version):
199197
return get_date_field(self._data, name)
200198
else:
201199
raise ImportError(
202-
"The {!r} accessor requires a minimum "
203-
"version of cftime of {}. Found an "
204-
"installed version of {}.".format(name, min_cftime_version, version)
200+
f"The {name:!r} accessor requires a minimum "
201+
f"version of cftime of {min_cftime_version}. Found an "
202+
f"installed version of {cftime.__version__}."
205203
)
206204

207205
f.__name__ = name

xarray/coding/times.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -400,8 +400,9 @@ def _cleanup_netcdf_time_units(units):
400400
delta, ref_date = _unpack_netcdf_time_units(units)
401401
try:
402402
units = "{} since {}".format(delta, format_timestamp(ref_date))
403-
except OutOfBoundsDatetime:
404-
# don't worry about reifying the units if they're out of bounds
403+
except (OutOfBoundsDatetime, ValueError):
404+
# don't worry about reifying the units if they're out of bounds or
405+
# formatted badly
405406
pass
406407
return units
407408

@@ -482,7 +483,7 @@ def encode_cf_datetime(dates, units=None, calendar=None):
482483
num = time_deltas / time_delta
483484
num = num.values.reshape(dates.shape)
484485

485-
except (OutOfBoundsDatetime, OverflowError):
486+
except (OutOfBoundsDatetime, OverflowError, ValueError):
486487
num = _encode_datetime_with_cftime(dates, units, calendar)
487488

488489
num = cast_to_int_if_safe(num)

xarray/core/dask_array_compat.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import warnings
22

33
import numpy as np
4+
from packaging.version import Version
45

56
from .pycompat import dask_version
67

@@ -56,7 +57,7 @@ def pad(array, pad_width, mode="constant", **kwargs):
5657
return padded
5758

5859

59-
if dask_version > "2.30.0":
60+
if dask_version > Version("2.30.0"):
6061
ensure_minimum_chunksize = da.overlap.ensure_minimum_chunksize
6162
else:
6263

@@ -113,7 +114,7 @@ def ensure_minimum_chunksize(size, chunks):
113114
return tuple(output)
114115

115116

116-
if dask_version > "2021.03.0":
117+
if dask_version > Version("2021.03.0"):
117118
sliding_window_view = da.lib.stride_tricks.sliding_window_view
118119
else:
119120

@@ -179,7 +180,7 @@ def sliding_window_view(x, window_shape, axis=None):
179180
axis=axis,
180181
)
181182
# map_overlap's signature changed in https://github.com/dask/dask/pull/6165
182-
if dask_version > "2.18.0":
183+
if dask_version > Version("2.18.0"):
183184
return map_overlap(_np_sliding_window_view, x, align_arrays=False, **kwargs)
184185
else:
185186
return map_overlap(x, _np_sliding_window_view, **kwargs)

xarray/core/dataset.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -1069,14 +1069,14 @@ def persist(self, **kwargs) -> "Dataset":
10691069
@classmethod
10701070
def _construct_direct(
10711071
cls,
1072-
variables,
1073-
coord_names,
1074-
dims=None,
1075-
attrs=None,
1076-
indexes=None,
1077-
encoding=None,
1078-
close=None,
1079-
):
1072+
variables: Dict[Any, Variable],
1073+
coord_names: Set[Hashable],
1074+
dims: Dict[Any, int] = None,
1075+
attrs: Dict = None,
1076+
indexes: Dict[Any, Index] = None,
1077+
encoding: Dict = None,
1078+
close: Callable[[], None] = None,
1079+
) -> "Dataset":
10801080
"""Shortcut around __init__ for internal use when we want to skip
10811081
costly validation
10821082
"""
@@ -2360,7 +2360,7 @@ def isel(
23602360
indexers = drop_dims_from_indexers(indexers, self.dims, missing_dims)
23612361

23622362
variables = {}
2363-
dims: Dict[Hashable, Tuple[int, ...]] = {}
2363+
dims: Dict[Hashable, int] = {}
23642364
coord_names = self._coord_names.copy()
23652365
indexes = self._indexes.copy() if self._indexes is not None else None
23662366

xarray/core/duck_array_ops.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from numpy import stack as _stack
2121
from numpy import take, tensordot, transpose, unravel_index # noqa
2222
from numpy import where as _where
23+
from packaging.version import Version
2324

2425
from . import dask_array_compat, dask_array_ops, dtypes, npcompat, nputils
2526
from .nputils import nanfirst, nanlast
@@ -175,7 +176,7 @@ def cumulative_trapezoid(y, x, axis):
175176
def astype(data, dtype, **kwargs):
176177
if (
177178
isinstance(data, sparse_array_type)
178-
and sparse_version < "0.11.0"
179+
and sparse_version < Version("0.11.0")
179180
and "casting" in kwargs
180181
):
181182
warnings.warn(

xarray/core/indexing.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import numpy as np
1010
import pandas as pd
11+
from packaging.version import Version
1112

1213
from . import duck_array_ops, nputils, utils
1314
from .npcompat import DTypeLike
@@ -1234,7 +1235,7 @@ def __getitem__(self, key):
12341235
return value
12351236

12361237
def __setitem__(self, key, value):
1237-
if dask_version >= "2021.04.1":
1238+
if dask_version >= Version("2021.04.1"):
12381239
if isinstance(key, BasicIndexer):
12391240
self.array[key.tuple] = value
12401241
elif isinstance(key, VectorizedIndexer):

xarray/core/missing.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import numpy as np
88
import pandas as pd
9+
from packaging.version import Version
910

1011
from . import utils
1112
from .common import _contains_datetime_like_objects, ones_like
@@ -741,7 +742,7 @@ def interp_func(var, x, new_x, method, kwargs):
741742
else:
742743
dtype = var.dtype
743744

744-
if dask_version < "2020.12":
745+
if dask_version < Version("2020.12"):
745746
# Using meta and dtype at the same time doesn't work.
746747
# Remove this whenever the minimum requirement for dask is 2020.12:
747748
meta = None

xarray/core/npcompat.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@
2929
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3030
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3131
import sys
32-
from distutils.version import LooseVersion
3332
from typing import TYPE_CHECKING, Any, Sequence, TypeVar, Union
3433

3534
import numpy as np
35+
from packaging.version import Version
3636

3737
# Type annotations stubs
3838
try:
@@ -79,7 +79,7 @@ def __array__(self) -> np.ndarray:
7979
DTypeLike = Union[np.dtype, str] # type: ignore[misc]
8080

8181

82-
if LooseVersion(np.__version__) >= "1.20.0":
82+
if Version(np.__version__) >= Version("1.20.0"):
8383
sliding_window_view = np.lib.stride_tricks.sliding_window_view
8484
else:
8585
from numpy.core.numeric import normalize_axis_tuple # type: ignore[attr-defined]

xarray/core/pdcompat.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,11 @@
3737
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3838
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3939

40-
from distutils.version import LooseVersion
41-
4240
import pandas as pd
41+
from packaging.version import Version
4342

4443
# allow ourselves to type checks for Panel even after it's removed
45-
if LooseVersion(pd.__version__) < "0.25.0":
44+
if Version(pd.__version__) < Version("0.25.0"):
4645
Panel = pd.Panel
4746
else:
4847

0 commit comments

Comments
 (0)