Skip to content

Commit d906488

Browse files
committed
MAINT: sparse: bump to 0.16b3
1 parent 308fc1f commit d906488

File tree

7 files changed

+79
-115
lines changed

7 files changed

+79
-115
lines changed

Diff for: pixi.lock

+48-73
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: pyproject.toml

+7-8
Original file line numberDiff line numberDiff line change
@@ -124,22 +124,21 @@ python = "~=3.10.0"
124124
python = "~=3.13.0"
125125

126126
# Backends that can run on CPU-only hosts
127-
[tool.pixi.feature.backends.target.linux-64.dependencies]
127+
[tool.pixi.feature.backends.dependencies]
128128
pytorch = "*"
129129
dask = "*"
130-
sparse = ">=0.15"
130+
numba = "*" # sparse dependency
131+
132+
[tool.pixi.feature.backends.pypi-dependencies]
133+
sparse = { version = ">= 0.16.0b3" }
134+
135+
[tool.pixi.feature.backends.target.linux-64.dependencies]
131136
jax = "*"
132137

133138
[tool.pixi.feature.backends.target.osx-arm64.dependencies]
134-
pytorch = "*"
135-
dask = "*"
136-
sparse = ">=0.15"
137139
jax = "*"
138140

139141
[tool.pixi.feature.backends.target.win-64.dependencies]
140-
pytorch = "*"
141-
dask = "*"
142-
sparse = ">=0.15"
143142
# jax = "*" # unavailable
144143

145144
# Backends that require a GPU host and a CUDA driver

Diff for: src/array_api_extra/_delegation.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ def pad(
125125
pad_width: int | tuple[int, int] | Sequence[tuple[int, int]],
126126
mode: Literal["constant"] = "constant",
127127
*,
128-
constant_values: bool | int | float | complex = 0,
128+
constant_values: complex = 0,
129129
xp: ModuleType | None = None,
130130
) -> Array:
131131
"""
@@ -168,7 +168,7 @@ def pad(
168168
pad_width = xp.flip(pad_width, axis=(0,)).flatten()
169169
return xp.nn.functional.pad(x, tuple(pad_width), value=constant_values) # type: ignore[arg-type] # pyright: ignore[reportArgumentType]
170170

171-
if _delegate(xp, Backend.NUMPY, Backend.JAX, Backend.CUPY):
171+
if _delegate(xp, Backend.NUMPY, Backend.JAX, Backend.CUPY, Backend.SPARSE):
172172
return xp.pad(x, pad_width, mode, constant_values=constant_values)
173173

174174
return _funcs.pad(x, pad_width, constant_values=constant_values, xp=xp)

Diff for: src/array_api_extra/_lib/_funcs.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,7 @@ def pad(
575575
x: Array,
576576
pad_width: int | tuple[int, int] | Sequence[tuple[int, int]],
577577
*,
578-
constant_values: bool | int | float | complex = 0,
578+
constant_values: complex = 0,
579579
xp: ModuleType,
580580
) -> Array: # numpydoc ignore=PR01,RT01
581581
"""See docstring in `array_api_extra._delegation.py`."""

Diff for: tests/test_funcs.py

+16-20
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
lazy_xp_function(sinc, static_argnames="xp")
4343

4444

45-
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no expand_dims")
4645
class TestAtLeastND:
4746
def test_0D(self, xp: ModuleType):
4847
x = xp.asarray(1.0)
@@ -69,7 +68,7 @@ def test_1D(self, xp: ModuleType):
6968
xp_assert_equal(y, xp.asarray([[0, 1]]))
7069

7170
y = atleast_nd(x, ndim=5)
72-
xp_assert_equal(y, xp.reshape(xp.arange(2), (1, 1, 1, 1, 2)))
71+
xp_assert_equal(y, xp.asarray([[[[[0, 1]]]]]))
7372

7473
def test_2D(self, xp: ModuleType):
7574
x = xp.asarray([[3.0]])
@@ -218,8 +217,10 @@ def test_xp(self, xp: ModuleType):
218217
)
219218

220219

220+
@pytest.mark.skip_xp_backend(
221+
Backend.SPARSE, reason="read-only backend without .at support"
222+
)
221223
class TestCreateDiagonal:
222-
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no device kwarg in zeros()")
223224
def test_1d_from_numpy(self, xp: ModuleType):
224225
# from np.diag tests
225226
vals = 100 * xp.arange(5, dtype=xp.float64)
@@ -235,7 +236,6 @@ def test_1d_from_numpy(self, xp: ModuleType):
235236
xp_assert_equal(create_diagonal(vals, offset=2), b)
236237
xp_assert_equal(create_diagonal(vals, offset=-2), c)
237238

238-
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no device kwarg in zeros()")
239239
@pytest.mark.parametrize("n", range(1, 10))
240240
@pytest.mark.parametrize("offset", range(1, 10))
241241
def test_1d_from_scipy(self, xp: ModuleType, n: int, offset: int):
@@ -251,7 +251,6 @@ def test_0d_raises(self, xp: ModuleType):
251251
with pytest.raises(ValueError, match="1-dimensional"):
252252
_ = create_diagonal(xp.asarray(1))
253253

254-
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no device kwarg in zeros()")
255254
@pytest.mark.parametrize(
256255
"shape",
257256
[
@@ -277,21 +276,19 @@ def test_nd(self, xp: ModuleType, shape: tuple[int, ...]):
277276
for i in ndindex(*eager_shape(c)):
278277
xp_assert_equal(c[i], b[i[:-1]] if i[-2] == i[-1] else zero)
279278

280-
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no device kwarg in zeros()")
281279
def test_device(self, xp: ModuleType, device: Device):
282280
x = xp.asarray([1, 2, 3], device=device)
283281
assert get_device(create_diagonal(x)) == device
284282

285-
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no device kwarg in zeros()")
286283
def test_xp(self, xp: ModuleType):
287284
x = xp.asarray([1, 2])
288285
y = create_diagonal(x, xp=xp)
289286
xp_assert_equal(y, xp.asarray([[1, 0], [0, 2]]))
290287

291288

292289
class TestExpandDims:
293-
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no expand_dims")
294290
@pytest.mark.xfail_xp_backend(Backend.DASK, reason="tuple index out of range")
291+
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="tuple index out of range")
295292
@pytest.mark.xfail_xp_backend(Backend.TORCH, reason="tuple index out of range")
296293
def test_functionality(self, xp: ModuleType):
297294
def _squeeze_all(b: Array) -> Array:
@@ -308,7 +305,6 @@ def _squeeze_all(b: Array) -> Array:
308305
assert b.shape[axis] == 1
309306
assert _squeeze_all(b).shape == s
310307

311-
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no expand_dims")
312308
def test_axis_tuple(self, xp: ModuleType):
313309
a = xp.empty((3, 3, 3))
314310
assert expand_dims(a, axis=(0, 1, 2)).shape == (1, 1, 1, 3, 3, 3)
@@ -341,12 +337,10 @@ def test_positive_negative_repeated(self, xp: ModuleType):
341337
with pytest.raises(ValueError, match="Duplicate dimensions"):
342338
_ = expand_dims(a, axis=(3, -3))
343339

344-
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no expand_dims")
345340
def test_device(self, xp: ModuleType, device: Device):
346341
x = xp.asarray([1, 2, 3], device=device)
347342
assert get_device(expand_dims(x, axis=0)) == device
348343

349-
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no expand_dims")
350344
def test_xp(self, xp: ModuleType):
351345
x = xp.asarray([1, 2, 3])
352346
y = expand_dims(x, axis=(0, 1, 2), xp=xp)
@@ -513,7 +507,6 @@ def test_xp(self, xp: ModuleType):
513507
xp_assert_equal(isclose(a, b, xp=xp), xp.asarray([True, False]))
514508

515509

516-
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no expand_dims")
517510
class TestKron:
518511
def test_basic(self, xp: ModuleType):
519512
# Using 0-dimensional array
@@ -572,6 +565,7 @@ def test_kron_shape(
572565
k = kron(a, b)
573566
assert k.shape == expected_shape
574567

568+
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no isdtype")
575569
def test_python_scalar(self, xp: ModuleType):
576570
a = 1
577571
# Test no dtype promotion to xp.asarray(a); use b.dtype
@@ -614,25 +608,27 @@ def test_xp(self, xp: ModuleType):
614608
xp_assert_equal(nunique(a, xp=xp), xp.asarray(3))
615609

616610

617-
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no arange, no device")
618611
class TestPad:
619612
def test_simple(self, xp: ModuleType):
620-
a = xp.arange(1, 4)
613+
a = xp.asarray([1, 2, 3])
621614
padded = pad(a, 2)
622615
xp_assert_equal(padded, xp.asarray([0, 0, 1, 2, 3, 0, 0]))
623616

617+
@pytest.mark.xfail_xp_backend(
618+
Backend.SPARSE, reason="constant_values can only be equal to fill value"
619+
)
624620
def test_fill_value(self, xp: ModuleType):
625-
a = xp.arange(1, 4)
621+
a = xp.asarray([1, 2, 3])
626622
padded = pad(a, 2, constant_values=42)
627623
xp_assert_equal(padded, xp.asarray([42, 42, 1, 2, 3, 42, 42]))
628624

629625
def test_ndim(self, xp: ModuleType):
630-
a = xp.reshape(xp.arange(2 * 3 * 4), (2, 3, 4))
626+
a = xp.asarray(np.reshape(np.arange(2 * 3 * 4), (2, 3, 4)))
631627
padded = pad(a, 2)
632628
assert padded.shape == (6, 7, 8)
633629

634630
def test_mode_not_implemented(self, xp: ModuleType):
635-
a = xp.arange(3)
631+
a = xp.asarray([1, 2, 3])
636632
with pytest.raises(NotImplementedError, match="Only `'constant'`"):
637633
_ = pad(a, 2, mode="edge") # type: ignore[arg-type] # pyright: ignore[reportArgumentType]
638634

@@ -645,7 +641,7 @@ def test_xp(self, xp: ModuleType):
645641
xp_assert_equal(padded, xp.asarray(0))
646642

647643
def test_tuple_width(self, xp: ModuleType):
648-
a = xp.reshape(xp.arange(12), (3, 4))
644+
a = xp.asarray(np.reshape(np.arange(12), (3, 4)))
649645
padded = pad(a, (1, 0))
650646
assert padded.shape == (4, 5)
651647

@@ -656,7 +652,7 @@ def test_tuple_width(self, xp: ModuleType):
656652
_ = pad(a, [(1, 2, 3)]) # type: ignore[list-item] # pyright: ignore[reportArgumentType]
657653

658654
def test_sequence_of_tuples_width(self, xp: ModuleType):
659-
a = xp.reshape(xp.arange(12), (3, 4))
655+
a = xp.asarray(np.reshape(np.arange(12), (3, 4)))
660656

661657
padded = pad(a, ((1, 0), (0, 2)))
662658
assert padded.shape == (4, 6)
@@ -678,7 +674,7 @@ def test_sequence_of_tuples_width(self, xp: ModuleType):
678674
)
679675

680676

681-
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no device kwarg in asarray()")
677+
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no argsort")
682678
class TestSetDiff1D:
683679
@pytest.mark.xfail_xp_backend(Backend.DASK, reason="NaN-shaped arrays")
684680
@pytest.mark.xfail_xp_backend(

Diff for: tests/test_helpers.py

+4-10
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,8 @@
1717
lazy_xp_function(in1d, jax_jit=False, static_argnames=("assume_unique", "invert", "xp"))
1818

1919

20+
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no unique_inverse")
2021
class TestIn1D:
21-
@pytest.mark.xfail_xp_backend(
22-
Backend.SPARSE, reason="no unique_inverse, no device kwarg in asarray()"
23-
)
2422
# cover both code paths
2523
@pytest.mark.parametrize(
2624
"n",
@@ -42,19 +40,15 @@ def test_no_invert_assume_unique(self, xp: ModuleType, n: int):
4240
actual = in1d(x1, x2)
4341
xp_assert_equal(actual, expected)
4442

45-
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no device kwarg in asarray")
4643
def test_device(self, xp: ModuleType, device: Device):
4744
x1 = xp.asarray([3, 8, 20], device=device)
4845
x2 = xp.asarray([2, 3, 4], device=device)
4946
assert get_device(in1d(x1, x2)) == device
5047

5148
@pytest.mark.skip_xp_backend(Backend.NUMPY_READONLY, reason="xp=xp")
52-
@pytest.mark.xfail_xp_backend(
53-
Backend.SPARSE, reason="no arange, no device kwarg in asarray"
54-
)
5549
def test_xp(self, xp: ModuleType):
5650
x1 = xp.asarray([1, 6])
57-
x2 = xp.arange(5)
51+
x2 = xp.asarray([0, 1, 2, 3, 4])
5852
expected = xp.asarray([True, False])
5953
actual = in1d(x1, x2, xp=xp)
6054
xp_assert_equal(actual, expected)
@@ -90,7 +84,7 @@ class TestAsArrays:
9084
],
9185
)
9286
def test_array_vs_scalar(
93-
self, dtype: str, b: int | float | complex, defined: bool, xp: ModuleType
87+
self, dtype: str, b: complex, defined: bool, xp: ModuleType
9488
):
9589
a = xp.asarray(1, dtype=getattr(xp, dtype))
9690

@@ -158,7 +152,7 @@ def test_ndindex(shape: tuple[int, ...]):
158152
assert tuple(ndindex(*shape)) == tuple(np.ndindex(*shape))
159153

160154

161-
@pytest.mark.skip_xp_backend(Backend.SPARSE, reason="index by sparse array")
155+
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="index by sparse array")
162156
def test_eager_shape(xp: ModuleType, library: Backend):
163157
a = xp.asarray([1, 2, 3])
164158
# Lazy arrays, like Dask, have an eager shape until you slice them with

Diff for: tests/test_testing.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ def test_assert_close_tolerance(xp: ModuleType):
7272

7373

7474
@param_assert_equal_close
75-
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no bool indexing")
75+
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="index by sparse array")
7676
def test_assert_close_equal_none_shape(xp: ModuleType, func: Callable[..., None]): # type: ignore[no-any-explicit]
7777
"""On dask and other lazy backends, test that a shape with NaN's or None's
7878
can be compared to a real shape.

0 commit comments

Comments
 (0)