Skip to content

Commit d073b7e

Browse files
authored
Merge pull request #312 from lucascolley/rel-0.8.0
REL: prepare v0.8.0 release
2 parents 61b512e + 1cd079a commit d073b7e

File tree

6 files changed

+1004
-1004
lines changed

6 files changed

+1004
-1004
lines changed

pixi.lock

Lines changed: 977 additions & 981 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/array_api_extra/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
)
1818
from ._lib._lazy import lazy_apply
1919

20-
__version__ = "0.8.0.dev0"
20+
__version__ = "0.8.0"
2121

2222
# pylint: disable=duplicate-code
2323
__all__ = [

src/array_api_extra/_lib/_utils/_helpers.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,9 @@ def meta_namespace(
301301
return array_namespace(*metas)
302302

303303

304-
def capabilities(xp: ModuleType, *, device: Device | None = None) -> dict[str, int]:
304+
def capabilities(
305+
xp: ModuleType, *, device: Device | None = None
306+
) -> dict[str, int | None]:
305307
"""
306308
Return patched ``xp.__array_namespace_info__().capabilities()``.
307309
@@ -322,7 +324,11 @@ def capabilities(xp: ModuleType, *, device: Device | None = None) -> dict[str, i
322324
"""
323325
if is_pydata_sparse_namespace(xp):
324326
# No __array_namespace_info__(); no indexing by sparse arrays
325-
return {"boolean indexing": False, "data-dependent shapes": True}
327+
return {
328+
"boolean indexing": False,
329+
"data-dependent shapes": True,
330+
"max dimensions": None,
331+
}
326332
out = xp.__array_namespace_info__().capabilities()
327333
if is_jax_namespace(xp) and out["boolean indexing"]:
328334
# FIXME https://github.com/jax-ml/jax/issues/27418
@@ -418,7 +424,9 @@ class Pickler(pickle.Pickler): # numpydoc ignore=GL08
418424
"""
419425

420426
@override
421-
def persistent_id(self, obj: object) -> Literal[0, 1, None]: # pyright: ignore[reportIncompatibleMethodOverride] # numpydoc ignore=GL08
427+
def persistent_id(
428+
self, obj: object
429+
) -> Literal[0, 1, None]: # numpydoc ignore=GL08
422430
if isinstance(obj, cls):
423431
instances.append(obj) # type: ignore[arg-type]
424432
return 0
@@ -483,7 +491,7 @@ class Unpickler(pickle.Unpickler): # numpydoc ignore=GL08
483491
"""Mirror of the overridden Pickler in pickle_flatten."""
484492

485493
@override
486-
def persistent_load(self, pid: Literal[0, 1]) -> object: # pyright: ignore[reportIncompatibleMethodOverride] # numpydoc ignore=GL08
494+
def persistent_load(self, pid: Literal[0, 1]) -> object: # numpydoc ignore=GL08
487495
try:
488496
return next(iters[pid])
489497
except StopIteration as e:

tests/test_funcs.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,6 @@ def test_none(self, args: tuple[tuple[float | None, ...], ...]):
404404
assert actual == expect
405405

406406

407-
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no isdtype")
408407
class TestCov:
409408
def test_basic(self, xp: ModuleType):
410409
xp_assert_close(
@@ -417,6 +416,7 @@ def test_complex(self, xp: ModuleType):
417416
expect = xp.asarray([[1.0, -1.0j], [1.0j, 1.0]], dtype=xp.complex128)
418417
xp_assert_close(actual, expect)
419418

419+
@pytest.mark.skip_xp_backend(Backend.SPARSE, reason="matmul with nan fillvalue")
420420
def test_empty(self, xp: ModuleType):
421421
with warnings.catch_warnings(record=True):
422422
warnings.simplefilter("always", RuntimeWarning)
@@ -612,7 +612,6 @@ def test_xp(self, xp: ModuleType):
612612
xp_assert_equal(y, xp.asarray([[1, 0], [0, 2]]))
613613

614614

615-
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no __array_namespace_info__")
616615
class TestDefaultDType:
617616
def test_basic(self, xp: ModuleType):
618617
assert default_dtype(xp) == xp.empty(0).dtype
@@ -697,7 +696,9 @@ def test_xp(self, xp: ModuleType):
697696
@pytest.mark.filterwarnings( # array_api_strictest
698697
"ignore:invalid value encountered:RuntimeWarning:array_api_strict"
699698
)
700-
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no isdtype")
699+
@pytest.mark.filterwarnings( # sparse
700+
"ignore:invalid value encountered:RuntimeWarning:sparse"
701+
)
701702
class TestIsClose:
702703
@pytest.mark.parametrize("swap", [False, True])
703704
@pytest.mark.parametrize(
@@ -815,6 +816,7 @@ def test_bool_dtype(self, xp: ModuleType):
815816
isclose(xp.asarray(True), b, atol=1), xp.asarray([True, True, True])
816817
)
817818

819+
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="index by sparse array")
818820
@pytest.mark.skip_xp_backend(Backend.ARRAY_API_STRICTEST, reason="unknown shape")
819821
def test_none_shape(self, xp: ModuleType):
820822
a = xp.asarray([1, 5, 0])
@@ -823,6 +825,7 @@ def test_none_shape(self, xp: ModuleType):
823825
a = a[a < 5]
824826
xp_assert_equal(isclose(a, b), xp.asarray([True, False]))
825827

828+
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="index by sparse array")
826829
@pytest.mark.skip_xp_backend(Backend.ARRAY_API_STRICTEST, reason="unknown shape")
827830
def test_none_shape_bool(self, xp: ModuleType):
828831
a = xp.asarray([True, True, False])
@@ -919,7 +922,6 @@ def test_kron_shape(
919922
k = kron(a, b)
920923
assert k.shape == expected_shape
921924

922-
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no isdtype")
923925
def test_python_scalar(self, xp: ModuleType):
924926
a = 1
925927
# Test no dtype promotion to xp.asarray(a); use b.dtype
@@ -1138,8 +1140,8 @@ def test_xp(self, xp: ModuleType):
11381140
xp_assert_equal(actual, expected)
11391141

11401142

1141-
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no isdtype")
11421143
class TestSinc:
1144+
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no linspace")
11431145
def test_simple(self, xp: ModuleType):
11441146
xp_assert_equal(sinc(xp.asarray(0.0)), xp.asarray(1.0))
11451147
w = sinc(xp.linspace(-1, 1, 100))
@@ -1151,6 +1153,7 @@ def test_dtype(self, xp: ModuleType, x: int | complex):
11511153
with pytest.raises(ValueError, match="real floating data type"):
11521154
_ = sinc(xp.asarray(x))
11531155

1156+
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no arange")
11541157
def test_3d(self, xp: ModuleType):
11551158
x = xp.reshape(xp.arange(18, dtype=xp.float64), (3, 3, 2))
11561159
expected = xp.zeros((3, 3, 2), dtype=xp.float64)

tests/test_helpers.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ def test_xp(self, xp: ModuleType):
7979

8080

8181
class TestAsArrays:
82-
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no isdtype")
8382
@pytest.mark.parametrize(
8483
("dtype", "b", "defined"),
8584
[

tests/test_testing.py

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,7 @@ def test_device(self, xp: ModuleType, device: Device):
3838

3939

4040
class TestAssertEqualCloseLess:
41-
pr_assert_close = pytest.param( # pyright: ignore[reportUnannotatedClassAttribute]
42-
xp_assert_close,
43-
marks=pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no isdtype"),
44-
)
45-
46-
@pytest.mark.parametrize("func", [xp_assert_equal, pr_assert_close])
41+
@pytest.mark.parametrize("func", [xp_assert_equal, xp_assert_close])
4742
def test_assert_equal_close_basic(self, xp: ModuleType, func: Callable[..., None]):
4843
func(xp.asarray(0), xp.asarray(0))
4944
func(xp.asarray([1, 2]), xp.asarray([1, 2]))
@@ -75,7 +70,7 @@ def test_namespace(self, xp: ModuleType, func: Callable[..., None]):
7570
with pytest.raises(TypeError, match="list is not a supported array type"):
7671
func(xp.asarray([0]), [0])
7772

78-
@pytest.mark.parametrize("func", [xp_assert_equal, pr_assert_close, xp_assert_less])
73+
@pytest.mark.parametrize("func", [xp_assert_equal, xp_assert_close, xp_assert_less])
7974
def test_check_shape(self, xp: ModuleType, func: Callable[..., None]):
8075
a = xp.asarray([1] if func is xp_assert_less else [2])
8176
b = xp.asarray(2)
@@ -90,7 +85,7 @@ def test_check_shape(self, xp: ModuleType, func: Callable[..., None]):
9085
with pytest.raises(AssertionError, match="sizes do not match"):
9186
func(a, d, check_shape=False)
9287

93-
@pytest.mark.parametrize("func", [xp_assert_equal, pr_assert_close, xp_assert_less])
88+
@pytest.mark.parametrize("func", [xp_assert_equal, xp_assert_close, xp_assert_less])
9489
def test_check_dtype(self, xp: ModuleType, func: Callable[..., None]):
9590
a = xp.asarray(1 if func is xp_assert_less else 2)
9691
b = xp.asarray(2, dtype=xp.int16)
@@ -102,7 +97,7 @@ def test_check_dtype(self, xp: ModuleType, func: Callable[..., None]):
10297
with pytest.raises(AssertionError, match="Mismatched elements"):
10398
func(a, c, check_dtype=False)
10499

105-
@pytest.mark.parametrize("func", [xp_assert_equal, pr_assert_close, xp_assert_less])
100+
@pytest.mark.parametrize("func", [xp_assert_equal, xp_assert_close, xp_assert_less])
106101
@pytest.mark.xfail_xp_backend(
107102
Backend.SPARSE, reason="sparse [()] returns np.generic"
108103
)
@@ -122,7 +117,6 @@ def test_check_scalar(
122117
with pytest.raises(AssertionError, match="Mismatched elements"):
123118
func(a, c, check_scalar=True)
124119

125-
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="no isdtype")
126120
@pytest.mark.parametrize("dtype", ["int64", "float64"])
127121
def test_assert_close_tolerance(self, dtype: str, xp: ModuleType):
128122
a = xp.asarray([100], dtype=getattr(xp, dtype))
@@ -145,7 +139,7 @@ def test_assert_less(self, xp: ModuleType):
145139
with pytest.raises(AssertionError, match="Mismatched elements"):
146140
xp_assert_less(xp.asarray([1, 1]), xp.asarray([2, 1]))
147141

148-
@pytest.mark.parametrize("func", [xp_assert_equal, pr_assert_close, xp_assert_less])
142+
@pytest.mark.parametrize("func", [xp_assert_equal, xp_assert_close, xp_assert_less])
149143
@pytest.mark.xfail_xp_backend(Backend.SPARSE, reason="index by sparse array")
150144
@pytest.mark.skip_xp_backend(Backend.ARRAY_API_STRICTEST, reason="boolean indexing")
151145
def test_none_shape(self, xp: ModuleType, func: Callable[..., None]):
@@ -176,7 +170,7 @@ def test_none_shape(self, xp: ModuleType, func: Callable[..., None]):
176170
with pytest.raises(AssertionError, match="Mismatched elements"):
177171
func(xp.asarray([4]), a)
178172

179-
@pytest.mark.parametrize("func", [xp_assert_equal, pr_assert_close, xp_assert_less])
173+
@pytest.mark.parametrize("func", [xp_assert_equal, xp_assert_close, xp_assert_less])
180174
def test_device(self, xp: ModuleType, device: Device, func: Callable[..., None]):
181175
a = xp.asarray([1] if func is xp_assert_less else [2], device=device)
182176
b = xp.asarray([2], device=device)

0 commit comments

Comments
 (0)