(type)
| 343 | |
| 344 | @pytest.mark.parametrize("type", ["pybind11", "numpy"]) |
| 345 | def test_to_pybuffer_contiguity(type): |
| 346 | def check_strides(mat): |
| 347 | # The full block is memset to 0, so fill it with non-zero in real spots. |
| 348 | expected = np.arange(1, 5 * 4 + 1).reshape((5, 4)) |
| 349 | for i in range(5): |
| 350 | for j in range(4): |
| 351 | mat[i, j] = expected[i, j] |
| 352 | # If all strides are correct, the exposed buffer should match the input. |
| 353 | np.testing.assert_array_equal(np.array(mat), expected) |
| 354 | |
| 355 | if type == "pybind11": |
| 356 | cmat = m.Matrix(5, 4) # C contiguous. |
| 357 | fmat = m.FortranMatrix(5, 4) # Fortran contiguous. |
| 358 | dmat = m.DiscontiguousMatrix(5, 4, 2, 3) # Not contiguous. |
| 359 | expected_exception = BufferError |
| 360 | elif type == "numpy": |
| 361 | cmat = np.empty((5, 4), dtype=np.float32) # C contiguous. |
| 362 | fmat = np.empty((5, 4), dtype=np.float32, order="F") # Fortran contiguous. |
| 363 | dmat = np.empty((5 * 2, 4 * 3), dtype=np.float32)[::2, ::3] # Not contiguous. |
| 364 | # NumPy incorrectly raises ValueError; when the minimum NumPy requirement is |
| 365 | # above the version that fixes https://github.com/numpy/numpy/issues/3634 then |
| 366 | # BufferError can be used everywhere. |
| 367 | expected_exception = (BufferError, ValueError) |
| 368 | else: |
| 369 | raise ValueError(f"Unknown parametrization {type}") |
| 370 | |
| 371 | check_strides(cmat) |
| 372 | # Should work in C-contiguous mode, but not Fortran order. |
| 373 | m.get_py_buffer(cmat, m.PyBUF_C_CONTIGUOUS) |
| 374 | m.get_py_buffer(cmat, m.PyBUF_ANY_CONTIGUOUS) |
| 375 | with pytest.raises(expected_exception): |
| 376 | m.get_py_buffer(cmat, m.PyBUF_F_CONTIGUOUS) |
| 377 | |
| 378 | check_strides(fmat) |
| 379 | # These flags imply C-contiguity, so won't work. |
| 380 | with pytest.raises(expected_exception): |
| 381 | m.get_py_buffer(fmat, m.PyBUF_SIMPLE) |
| 382 | with pytest.raises(expected_exception): |
| 383 | m.get_py_buffer(fmat, m.PyBUF_ND) |
| 384 | # Should work in Fortran-contiguous mode, but not C order. |
| 385 | with pytest.raises(expected_exception): |
| 386 | m.get_py_buffer(fmat, m.PyBUF_C_CONTIGUOUS) |
| 387 | m.get_py_buffer(fmat, m.PyBUF_ANY_CONTIGUOUS) |
| 388 | m.get_py_buffer(fmat, m.PyBUF_F_CONTIGUOUS) |
| 389 | |
| 390 | check_strides(dmat) |
| 391 | # Should never work. |
| 392 | with pytest.raises(expected_exception): |
| 393 | m.get_py_buffer(dmat, m.PyBUF_SIMPLE) |
| 394 | with pytest.raises(expected_exception): |
| 395 | m.get_py_buffer(dmat, m.PyBUF_ND) |
| 396 | with pytest.raises(expected_exception): |
| 397 | m.get_py_buffer(dmat, m.PyBUF_C_CONTIGUOUS) |
| 398 | with pytest.raises(expected_exception): |
| 399 | m.get_py_buffer(dmat, m.PyBUF_ANY_CONTIGUOUS) |
| 400 | with pytest.raises(expected_exception): |
| 401 | m.get_py_buffer(dmat, m.PyBUF_F_CONTIGUOUS) |
| 402 |
nothing calls this directly
no test coverage detected