Skip to content

Commit 96f9e94

Browse files
authored
import from the new location of normalize_axis_index if possible (#8483)
* import from the new location of `normalize_axis_index` if possible * disable build isolation for `cftime` [skip-ci] [skip-rtd] * actually apply the `--no-build-isolation` [skip-ci] [skip-rtd] * install `cython`, which is needed to build `cftime` * use `micromamba` instead of `conda` for removing packages * switch the main uninstall back to `conda` * temporarily remove `cf_units`, `h5py`, and `netcdf4` * also remove `hdf5` [skip-ci] * try building `numcodecs` from github and without build isolation * build `cftime` separately from `numcodecs` and install more deps [skip-ci] * don't uninstall packages that are already removed [skip-ci] * also build `bottleneck` without build isolation * use `module_available` instead of eagerly importing * add a `minversion` kwarg to `module_available` * use `module_available` in `nputils` as well * more type ignores * move the type ignores to the import * ignore complaints about unused ignores (the point here is compatibility between multiple versions) * a couple of other `type: ignore` comments (only relevant for nightly)
1 parent f4d2609 commit 96f9e94

File tree

4 files changed

+59
-15
lines changed

4 files changed

+59
-15
lines changed

ci/install-upstream-wheels.sh

+24-10
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,25 @@
11
#!/usr/bin/env bash
22

3+
# install cython for building cftime without build isolation
4+
micromamba install "cython>=0.29.20" py-cpuinfo
35
# temporarily (?) remove numbagg and numba
4-
pip uninstall -y numbagg
5-
conda uninstall -y numba
6+
micromamba remove -y numba numbagg
7+
# temporarily remove backends
8+
micromamba remove -y cf_units h5py hdf5 netcdf4
69
# forcibly remove packages to avoid artifacts
710
conda uninstall -y --force \
811
numpy \
912
scipy \
1013
pandas \
11-
matplotlib \
12-
dask \
1314
distributed \
1415
fsspec \
1516
zarr \
1617
cftime \
1718
packaging \
1819
pint \
1920
bottleneck \
20-
sparse \
2121
flox \
22-
h5netcdf \
23-
xarray
22+
numcodecs
2423
# to limit the runtime of Upstream CI
2524
python -m pip install \
2625
-i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple \
@@ -31,19 +30,34 @@ python -m pip install \
3130
scipy \
3231
matplotlib \
3332
pandas
33+
# without build isolation for packages compiling against numpy
34+
# TODO: remove once there are `numpy>=2.0` builds for numcodecs and cftime
35+
python -m pip install \
36+
--no-deps \
37+
--upgrade \
38+
--no-build-isolation \
39+
git+https://github.com/Unidata/cftime
40+
python -m pip install \
41+
--no-deps \
42+
--upgrade \
43+
--no-build-isolation \
44+
git+https://github.com/zarr-developers/numcodecs
45+
python -m pip install \
46+
--no-deps \
47+
--upgrade \
48+
--no-build-isolation \
49+
git+https://github.com/pydata/bottleneck
3450
python -m pip install \
3551
--no-deps \
3652
--upgrade \
3753
git+https://github.com/dask/dask \
3854
git+https://github.com/dask/distributed \
3955
git+https://github.com/zarr-developers/zarr \
40-
git+https://github.com/Unidata/cftime \
4156
git+https://github.com/pypa/packaging \
4257
git+https://github.com/hgrecco/pint \
43-
git+https://github.com/pydata/bottleneck \
4458
git+https://github.com/pydata/sparse \
4559
git+https://github.com/intake/filesystem_spec \
4660
git+https://github.com/SciTools/nc-time-axis \
4761
git+https://github.com/xarray-contrib/flox \
48-
git+https://github.com/h5netcdf/h5netcdf \
4962
git+https://github.com/dgasmith/opt_einsum
63+
# git+https://github.com/h5netcdf/h5netcdf

xarray/core/duck_array_ops.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
zeros_like, # noqa
3030
)
3131
from numpy import concatenate as _concatenate
32-
from numpy.core.multiarray import normalize_axis_index # type: ignore[attr-defined]
3332
from numpy.lib.stride_tricks import sliding_window_view # noqa
3433
from packaging.version import Version
3534

@@ -39,6 +38,17 @@
3938
from xarray.core.pycompat import array_type, is_duck_dask_array
4039
from xarray.core.utils import is_duck_array, module_available
4140

41+
# remove once numpy 2.0 is the oldest supported version
42+
if module_available("numpy", minversion="2.0.0.dev0"):
43+
from numpy.lib.array_utils import ( # type: ignore[import-not-found,unused-ignore]
44+
normalize_axis_index,
45+
)
46+
else:
47+
from numpy.core.multiarray import ( # type: ignore[attr-defined,no-redef,unused-ignore]
48+
normalize_axis_index,
49+
)
50+
51+
4252
dask_available = module_available("dask")
4353

4454

xarray/core/nputils.py

+11-2
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,26 @@
55

66
import numpy as np
77
import pandas as pd
8-
from numpy.core.multiarray import normalize_axis_index # type: ignore[attr-defined]
98
from packaging.version import Version
109

1110
from xarray.core import pycompat
1211
from xarray.core.utils import module_available
1312

13+
# remove once numpy 2.0 is the oldest supported version
14+
if module_available("numpy", minversion="2.0.0.dev0"):
15+
from numpy.lib.array_utils import ( # type: ignore[import-not-found,unused-ignore]
16+
normalize_axis_index,
17+
)
18+
else:
19+
from numpy.core.multiarray import ( # type: ignore[attr-defined,no-redef,unused-ignore]
20+
normalize_axis_index,
21+
)
22+
1423
# remove once numpy 2.0 is the oldest supported version
1524
try:
1625
from numpy.exceptions import RankWarning # type: ignore[attr-defined,unused-ignore]
1726
except ImportError:
18-
from numpy import RankWarning
27+
from numpy import RankWarning # type: ignore[attr-defined,no-redef,unused-ignore]
1928

2029
from xarray.core.options import OPTIONS
2130
from xarray.core.pycompat import is_duck_array

xarray/core/utils.py

+13-2
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373

7474
import numpy as np
7575
import pandas as pd
76+
from packaging.version import Version
7677

7778
if TYPE_CHECKING:
7879
from xarray.core.types import Dims, ErrorOptionsWithWarn, T_DuckArray
@@ -1194,7 +1195,7 @@ def contains_only_chunked_or_numpy(obj) -> bool:
11941195
)
11951196

11961197

1197-
def module_available(module: str) -> bool:
1198+
def module_available(module: str, minversion: str | None = None) -> bool:
11981199
"""Checks whether a module is installed without importing it.
11991200
12001201
Use this for a lightweight check and lazy imports.
@@ -1203,13 +1204,23 @@ def module_available(module: str) -> bool:
12031204
----------
12041205
module : str
12051206
Name of the module.
1207+
minversion : str, optional
1208+
Minimum version of the module
12061209
12071210
Returns
12081211
-------
12091212
available : bool
12101213
Whether the module is installed.
12111214
"""
1212-
return importlib.util.find_spec(module) is not None
1215+
if importlib.util.find_spec(module) is None:
1216+
return False
1217+
1218+
if minversion is not None:
1219+
version = importlib.metadata.version(module)
1220+
1221+
return Version(version) >= Version(minversion)
1222+
1223+
return True
12131224

12141225

12151226
def find_stack_level(test_mode=False) -> int:

0 commit comments

Comments
 (0)