Skip to content
Draft
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions array_api_tests/pytest_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from .typing import Array, DataType, Scalar, ScalarType, Shape

__all__ = [
"add_note",
"raises",
"doesnt_raise",
"nargs",
Expand All @@ -31,6 +32,24 @@
]


def add_note(exc, note):
"""
Add a note to an exception in a backward-compatible way.
For Python 3.11+, this uses the built-in exc.add_note() method.
For earlier versions, it manually appends to exc.__notes__.
"""
try:
exc.add_note(note)
except AttributeError:
if not hasattr(exc, "__notes__"):
try:
exc.__notes__ = []
except AttributeError:
return # give up, might be e.g. a frozen dataclass
exc.__notes__.append(note)


def raises(exceptions, function, message=""):
"""
Like pytest.raises() except it allows custom error messages
Expand Down
2 changes: 1 addition & 1 deletion array_api_tests/test_array_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def test_getitem(shape, dtype, data):
expected = xp.asarray(out_obj, dtype=dtype)
ph.assert_array_elements("__getitem__", out=out, expected=expected)
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise

@pytest.mark.unvectorized
Expand Down
28 changes: 14 additions & 14 deletions array_api_tests/test_creation_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ def test_arange(dtype, data):
out[0], xp.asarray(_start, dtype=out.dtype)
), f"out[0]={out[0]}, but should be {_start} {f_func}"
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand Down Expand Up @@ -257,7 +257,7 @@ def test_asarray_scalars(shape, data):
v = scalar_type(out[idx])
ph.assert_scalar_equals("asarray", type_=scalar_type, idx=idx, out=v, expected=v_expect, kw=kw)
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise

def scalar_eq(s1: Scalar, s2: Scalar) -> bool:
Expand Down Expand Up @@ -323,7 +323,7 @@ def test_asarray_arrays(shape, dtypes, data):
new_out_value, value
), f"{f_out}, but should be {value} after x was mutated"
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand All @@ -339,7 +339,7 @@ def test_empty(shape, kw):
ph.assert_kw_dtype("empty", kw_dtype=kw["dtype"], out_dtype=out.dtype)
ph.assert_shape("empty", out_shape=out.shape, expected=shape, kw=dict(shape=shape))
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand All @@ -357,7 +357,7 @@ def test_empty_like(x, kw):
ph.assert_kw_dtype("empty_like", kw_dtype=kw["dtype"], out_dtype=out.dtype)
ph.assert_shape("empty_like", out_shape=out.shape, expected=x.shape)
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise

@given(
Expand Down Expand Up @@ -387,7 +387,7 @@ def test_eye(n_rows, n_cols, kw):
expected = xp.reshape(expected, (n_rows, _n_cols))
ph.assert_array_elements("eye", out=out, expected=expected, kw=kw)
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand Down Expand Up @@ -455,7 +455,7 @@ def test_full(shape, fill_value, kw):
ph.assert_shape("full", out_shape=out.shape, expected=shape, kw=dict(shape=shape))
ph.assert_fill("full", fill_value=fill_value, dtype=dtype, out=out, kw=dict(fill_value=fill_value))
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand All @@ -476,7 +476,7 @@ def test_full_like(kw, data):
ph.assert_shape("full_like", out_shape=out.shape, expected=x.shape)
ph.assert_fill("full_like", fill_value=fill_value, dtype=dtype, out=out, kw=dict(fill_value=fill_value))
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise

finite_kw = {"allow_nan": False, "allow_infinity": False}
Expand Down Expand Up @@ -534,7 +534,7 @@ def test_linspace(num, dtype, endpoint, data):
expected = expected[:-1]
ph.assert_array_elements("linspace", out=out, expected=expected)
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand Down Expand Up @@ -563,7 +563,7 @@ def test_meshgrid(dtype, data):
for i, x in enumerate(out):
ph.assert_dtype("meshgrid", in_dtype=dtype, out_dtype=x.dtype, repr_name=f"out[{i}].dtype")
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand All @@ -590,7 +590,7 @@ def test_ones(shape, kw):
dtype = kw.get("dtype", None) or dh.default_float
ph.assert_fill("ones", fill_value=make_one(dtype), dtype=dtype, out=out, kw=kw)
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand All @@ -611,7 +611,7 @@ def test_ones_like(x, kw):
ph.assert_fill("ones_like", fill_value=make_one(dtype), dtype=dtype,
out=out, kw=kw)
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand All @@ -638,7 +638,7 @@ def test_zeros(shape, kw):
ph.assert_fill("zeros", fill_value=make_zero(dtype), dtype=dtype, out=out,
kw=kw)
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand All @@ -660,5 +660,5 @@ def test_zeros_like(x, kw):
ph.assert_fill("zeros_like", fill_value=make_zero(dtype), dtype=dtype,
out=out, kw=kw)
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise
28 changes: 14 additions & 14 deletions array_api_tests/test_data_type_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def test_astype(x_dtype, dtype, kw, data):
# TODO: test values
# TODO: test copy
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand Down Expand Up @@ -124,7 +124,7 @@ def test_broadcast_arrays(shapes, data):
)
# TODO: test values
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand All @@ -145,7 +145,7 @@ def test_broadcast_to(x, data):
ph.assert_shape("broadcast_to", out_shape=out.shape, expected=shape)
# TODO: test values
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand All @@ -168,7 +168,7 @@ def test_can_cast(_from, to):
# check that the array library actually allows such casts.
assert out == expected, f"{out=}, but should be {expected} {f_func}"
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand All @@ -189,7 +189,7 @@ def test_finfo(dtype):
assert isinstance(out.min, float)
assert isinstance(out.smallest_normal, float)
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise

@pytest.mark.min_version("2022.12")
Expand All @@ -211,7 +211,7 @@ def test_finfo_dtype(dtype):
assert out.dtype is not float
assert out.dtype is not complex
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand All @@ -230,7 +230,7 @@ def test_iinfo(dtype):
assert isinstance(out.max, int)
assert isinstance(out.min, int)
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand All @@ -245,7 +245,7 @@ def test_iinfo_dtype(dtype):
assert not isinstance(out.dtype, str)
assert out.dtype is not int
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand Down Expand Up @@ -277,7 +277,7 @@ def test_isdtype(dtype, kind):
break
assert out == expected, f"{out=}, but should be {expected} [isdtype()]"
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand All @@ -290,7 +290,7 @@ def test_result_type(self, dtypes):
out = xp.result_type(*dtypes)
ph.assert_dtype("result_type", in_dtype=dtypes, out_dtype=out, repr_name="out")
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise

@given(pair=hh.pair_of_mutually_promotable_dtypes(None))
Expand All @@ -312,7 +312,7 @@ def test_arrays_and_dtypes(self, pair, data):
out = xp.result_type(*a_and_dt)
ph.assert_dtype("result_type", in_dtype=s1+s2, out_dtype=out, repr_name="out")
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise

@given(dtypes=hh.mutually_promotable_dtypes(2), data=st.data())
Expand All @@ -333,7 +333,7 @@ def test_with_scalars(self, dtypes, data):
else:
raise ValueError(f"unknown dtype {out = }.")
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise

scalar = data.draw(st.sampled_from(scalars))
Expand All @@ -344,7 +344,7 @@ def test_with_scalars(self, dtypes, data):
out_scalar = xp.result_type(*inputs)
assert out_scalar == out
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise

# retry with arrays
Expand All @@ -356,5 +356,5 @@ def test_with_scalars(self, dtypes, data):
out_scalar = xp.result_type(*inputs)
assert out_scalar == out
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise
24 changes: 12 additions & 12 deletions array_api_tests/test_manipulation_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ def test_concat(dtypes, base_shape, data):
kw=kw,
)
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand Down Expand Up @@ -152,7 +152,7 @@ def test_expand_dims(x, axis):
"expand_dims", x, x_indices=sh.ndindex(x.shape), out=out, out_indices=sh.ndindex(out.shape)
)
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand Down Expand Up @@ -202,7 +202,7 @@ def test_moveaxis(x, data):
"moveaxis", x, x_indices=sh.ndindex(x.shape), out=out, out_indices=permuted_indices
)
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand Down Expand Up @@ -245,7 +245,7 @@ def test_squeeze(x, data):

assert_array_ndindex("squeeze", x, x_indices=sh.ndindex(x.shape), out=out, out_indices=sh.ndindex(out.shape))
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand Down Expand Up @@ -275,7 +275,7 @@ def test_flip(x, data):
assert_array_ndindex("flip", x, x_indices=indices, out=out,
out_indices=reverse_indices, kw=kw)
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand Down Expand Up @@ -310,7 +310,7 @@ def test_permute_dims(x, axes):
assert_array_ndindex("permute_dims", x, x_indices=indices, out=out,
out_indices=permuted_indices)
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise

@pytest.mark.min_version("2023.12")
Expand Down Expand Up @@ -378,7 +378,7 @@ def test_repeat(x, kw, data):
start = end

except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand Down Expand Up @@ -406,7 +406,7 @@ def test_reshape(x, shape):

assert_array_ndindex("reshape", x, x_indices=sh.ndindex(x.shape), out=out, out_indices=sh.ndindex(out.shape))
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand Down Expand Up @@ -460,7 +460,7 @@ def test_roll(x, data):
shifted_indices = roll_ndindex(x.shape, shifts, axes)
assert_array_ndindex("roll", x, x_indices=sh.ndindex(x.shape), out=out, out_indices=shifted_indices, kw=kw)
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand Down Expand Up @@ -512,7 +512,7 @@ def test_stack(shape, dtypes, kw, data):
kw=kw,
)
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise


Expand Down Expand Up @@ -540,7 +540,7 @@ def test_tile(x, data):

assert out.shape == tuple(r*s for r, s in zip(R, S))
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise

@pytest.mark.min_version("2023.12")
Expand Down Expand Up @@ -571,5 +571,5 @@ def test_unstack(x, data):
idx[axis] = i
ph.assert_array_elements("unstack", out=arr, expected=x[tuple(idx)], kw=kw, out_repr=f"out[{i}]")
except Exception as exc:
exc.add_note(repro_snippet)
ph.add_note(exc, repro_snippet)
raise
Loading