Skip to content

Commit 25e8dd4

Browse files
committed
ENH: start adding "repro snippets" for failed assertions
It is not always easy to tell what exactly failed with hypothesis (gh-379). Thus add a failing snippet to the exceptions' output. For instance, run $ ARRAY_API_TESTS_MODULE=array_api_compat.torch pytest array_api_tests/test_array_object.py::test_getitem to see E ValueError: step must be greater than zero E E ========== FAILING CODE SNIPPET: E tensor([False, False])[(slice(1, 0, -1),)] E ====================
1 parent a434727 commit 25e8dd4

File tree

4 files changed

+304
-229
lines changed

4 files changed

+304
-229
lines changed

array_api_tests/pytest_helpers.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,3 +599,7 @@ def assert_array_elements(
599599
at_expected = expected[idx]
600600
msg = msg_template.format(sh.fmt_idx(out_repr, idx), at_out, at_expected)
601601
assert at_out == at_expected, msg
602+
603+
604+
def format_snippet(s: str):
605+
return f"\n{'='*10} FAILING CODE SNIPPET:\n{s}\n{'='*20}\n"

array_api_tests/test_array_object.py

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -85,24 +85,29 @@ def test_getitem(shape, dtype, data):
8585
note(f"{x=}")
8686
key = data.draw(xps.indices(shape=shape, allow_newaxis=True), label="key")
8787

88-
out = x[key]
89-
90-
ph.assert_dtype("__getitem__", in_dtype=x.dtype, out_dtype=out.dtype)
91-
_key = normalize_key(key, shape)
92-
axes_indices, expected_shape = get_indexed_axes_and_out_shape(_key, shape)
93-
ph.assert_shape("__getitem__", out_shape=out.shape, expected=expected_shape)
94-
out_zero_sided = any(side == 0 for side in expected_shape)
95-
if not zero_sided and not out_zero_sided:
96-
out_obj = []
97-
for idx in product(*axes_indices):
98-
val = obj
99-
for i in idx:
100-
val = val[i]
101-
out_obj.append(val)
102-
out_obj = sh.reshape(out_obj, expected_shape)
103-
expected = xp.asarray(out_obj, dtype=dtype)
104-
ph.assert_array_elements("__getitem__", out=out, expected=expected)
105-
88+
repro_snippet = ph.format_snippet(f"{x!r}[{key!r}]")
89+
90+
try:
91+
out = x[key]
92+
93+
ph.assert_dtype("__getitem__", in_dtype=x.dtype, out_dtype=out.dtype)
94+
_key = normalize_key(key, shape)
95+
axes_indices, expected_shape = get_indexed_axes_and_out_shape(_key, shape)
96+
ph.assert_shape("__getitem__", out_shape=out.shape, expected=expected_shape)
97+
out_zero_sided = any(side == 0 for side in expected_shape)
98+
if not zero_sided and not out_zero_sided:
99+
out_obj = []
100+
for idx in product(*axes_indices):
101+
val = obj
102+
for i in idx:
103+
val = val[i]
104+
out_obj.append(val)
105+
out_obj = sh.reshape(out_obj, expected_shape)
106+
expected = xp.asarray(out_obj, dtype=dtype)
107+
ph.assert_array_elements("__getitem__", out=out, expected=expected)
108+
except Exception as exc:
109+
exc.add_note(repro_snippet)
110+
raise
106111

107112
@pytest.mark.unvectorized
108113
@given(

array_api_tests/test_data_type_functions.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -160,13 +160,17 @@ def test_finfo(dtype):
160160
# np.float64 and np.asarray(1, dtype=np.float64).dtype are different
161161
xp.asarray(1, dtype=dtype).dtype,
162162
):
163-
out = xp.finfo(arg)
164-
assert isinstance(out.bits, int)
165-
assert isinstance(out.eps, float)
166-
assert isinstance(out.max, float)
167-
assert isinstance(out.min, float)
168-
assert isinstance(out.smallest_normal, float)
169-
163+
repro_snippet = ph.format_snippet(f"xp.finfo({arg})")
164+
try:
165+
out = xp.finfo(arg)
166+
assert isinstance(out.bits, int)
167+
assert isinstance(out.eps, float)
168+
assert isinstance(out.max, float)
169+
assert isinstance(out.min, float)
170+
assert isinstance(out.smallest_normal, float)
171+
except Exception as exc:
172+
exc.add_note(repro_snippet)
173+
raise
170174

171175
@pytest.mark.min_version("2022.12")
172176
@pytest.mark.parametrize("dtype", dh.real_float_dtypes + dh.complex_dtypes)

0 commit comments

Comments
 (0)