Skip to content

Commit ab096b0

Browse files
authored
unpin numpy (#8061)
* unpin `numpy` * dispatch to `np.empty_like` if there's no missing value * make sure there's no code path without `create_template` * declare `create_template` as callable * ignore the intentionally wrong typing * mark the ignore as intentional, even if it might not be used this important because the fix in `numpy` that now means we *don't* need it anymore has been around for less than 3 months (requires a sufficiently new version of `mypy`). * also directly check that `Variable.unstack` does not raise warnings * fix the unstack test
1 parent 06a756c commit ab096b0

File tree

9 files changed

+35
-12
lines changed

9 files changed

+35
-12
lines changed

ci/requirements/all-but-dask.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ dependencies:
2323
- netcdf4
2424
- numba
2525
- numbagg
26-
- numpy<1.24
26+
- numpy
2727
- packaging
2828
- pandas
2929
- pint<0.21

ci/requirements/doc.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ dependencies:
1919
- nbsphinx
2020
- netcdf4>=1.5
2121
- numba
22-
- numpy>=1.21,<1.24
22+
- numpy>=1.21
2323
- packaging>=21.3
2424
- pandas>=1.4
2525
- pooch

ci/requirements/environment-windows.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ dependencies:
2222
- netcdf4
2323
- numba
2424
- numbagg
25-
- numpy<1.24
25+
- numpy
2626
- packaging
2727
- pandas
2828
- pint<0.21

ci/requirements/environment.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ dependencies:
2525
- numba
2626
- numbagg
2727
- numexpr
28-
- numpy<1.24
28+
- numpy
2929
- packaging
3030
- pandas
3131
- pint<0.21

xarray/core/variable.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import warnings
88
from collections.abc import Hashable, Iterable, Mapping, Sequence
99
from datetime import timedelta
10+
from functools import partial
1011
from typing import TYPE_CHECKING, Any, Callable, Literal, NoReturn
1112

1213
import numpy as np
@@ -1836,15 +1837,20 @@ def _unstack_once(
18361837
new_shape = tuple(list(reordered.shape[: len(other_dims)]) + new_dim_sizes)
18371838
new_dims = reordered.dims[: len(other_dims)] + new_dim_names
18381839

1840+
create_template: Callable
18391841
if fill_value is dtypes.NA:
18401842
is_missing_values = math.prod(new_shape) > math.prod(self.shape)
18411843
if is_missing_values:
18421844
dtype, fill_value = dtypes.maybe_promote(self.dtype)
1845+
1846+
create_template = partial(np.full_like, fill_value=fill_value)
18431847
else:
18441848
dtype = self.dtype
18451849
fill_value = dtypes.get_fill_value(dtype)
1850+
create_template = np.empty_like
18461851
else:
18471852
dtype = self.dtype
1853+
create_template = partial(np.full_like, fill_value=fill_value)
18481854

18491855
if sparse:
18501856
# unstacking a dense multitindexed array to a sparse array
@@ -1867,12 +1873,7 @@ def _unstack_once(
18671873
)
18681874

18691875
else:
1870-
data = np.full_like(
1871-
self.data,
1872-
fill_value=fill_value,
1873-
shape=new_shape,
1874-
dtype=dtype,
1875-
)
1876+
data = create_template(self.data, shape=new_shape, dtype=dtype)
18761877

18771878
# Indexer is a list of lists of locations. Each list is the locations
18781879
# on the new dimension. This is robust to the data being sparse; in that

xarray/tests/test_coding_strings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def test_vlen_dtype() -> None:
3333
assert strings.check_vlen_dtype(dtype) is bytes
3434

3535
# check h5py variant ("vlen")
36-
dtype = np.dtype("O", metadata={"vlen": str}) # type: ignore[call-overload]
36+
dtype = np.dtype("O", metadata={"vlen": str}) # type: ignore[call-overload,unused-ignore]
3737
assert strings.check_vlen_dtype(dtype) is str
3838

3939
assert strings.check_vlen_dtype(np.dtype(object)) is None

xarray/tests/test_dataarray.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2490,6 +2490,19 @@ def test_unstack_pandas_consistency(self) -> None:
24902490
actual = DataArray(s, dims="z").unstack("z")
24912491
assert_identical(expected, actual)
24922492

2493+
@pytest.mark.filterwarnings("error")
2494+
def test_unstack_roundtrip_integer_array(self) -> None:
2495+
arr = xr.DataArray(
2496+
np.arange(6).reshape(2, 3),
2497+
coords={"x": ["a", "b"], "y": [0, 1, 2]},
2498+
dims=["x", "y"],
2499+
)
2500+
2501+
stacked = arr.stack(z=["x", "y"])
2502+
roundtripped = stacked.unstack()
2503+
2504+
assert_identical(arr, roundtripped)
2505+
24932506
def test_stack_nonunique_consistency(self, da) -> None:
24942507
da = da.isel(time=0, drop=True) # 2D
24952508
actual = da.stack(z=["a", "x"])

xarray/tests/test_groupby.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,7 @@ def test_groupby_dataset_iter() -> None:
728728
def test_groupby_dataset_errors() -> None:
729729
data = create_test_data()
730730
with pytest.raises(TypeError, match=r"`group` must be"):
731-
data.groupby(np.arange(10))
731+
data.groupby(np.arange(10)) # type: ignore
732732
with pytest.raises(ValueError, match=r"length does not match"):
733733
data.groupby(data["dim1"][:3])
734734
with pytest.raises(TypeError, match=r"`group` must be"):

xarray/tests/test_variable.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1707,6 +1707,15 @@ def test_stack_unstack_consistency(self):
17071707
actual = v.stack(z=("x", "y")).unstack(z={"x": 2, "y": 2})
17081708
assert_identical(actual, v)
17091709

1710+
@pytest.mark.filterwarnings("error::RuntimeWarning")
1711+
def test_unstack_without_missing(self):
1712+
v = Variable(["z"], [0, 1, 2, 3])
1713+
expected = Variable(["x", "y"], [[0, 1], [2, 3]])
1714+
1715+
actual = v.unstack(z={"x": 2, "y": 2})
1716+
1717+
assert_identical(actual, expected)
1718+
17101719
def test_broadcasting_math(self):
17111720
x = np.random.randn(2, 3)
17121721
v = Variable(["a", "b"], x)

0 commit comments

Comments
 (0)