1import struct 2import pytest 3from pybind11_tests import buffers as m 4from pybind11_tests import ConstructorStats 5 6pytestmark = pytest.requires_numpy 7 8with pytest.suppress(ImportError): 9 import numpy as np 10 11 12def test_from_python(): 13 with pytest.raises(RuntimeError) as excinfo: 14 m.Matrix(np.array([1, 2, 3])) # trying to assign a 1D array 15 assert str(excinfo.value) == "Incompatible buffer format!" 16 17 m3 = np.array([[1, 2, 3], [4, 5, 6]]).astype(np.float32) 18 m4 = m.Matrix(m3) 19 20 for i in range(m4.rows()): 21 for j in range(m4.cols()): 22 assert m3[i, j] == m4[i, j] 23 24 cstats = ConstructorStats.get(m.Matrix) 25 assert cstats.alive() == 1 26 del m3, m4 27 assert cstats.alive() == 0 28 assert cstats.values() == ["2x3 matrix"] 29 assert cstats.copy_constructions == 0 30 # assert cstats.move_constructions >= 0 # Don't invoke any 31 assert cstats.copy_assignments == 0 32 assert cstats.move_assignments == 0 33 34 35# PyPy: Memory leak in the "np.array(m, copy=False)" call 36# https://bitbucket.org/pypy/pypy/issues/2444 37@pytest.unsupported_on_pypy 38def test_to_python(): 39 mat = m.Matrix(5, 4) 40 assert memoryview(mat).shape == (5, 4) 41 42 assert mat[2, 3] == 0 43 mat[2, 3] = 4.0 44 mat[3, 2] = 7.0 45 assert mat[2, 3] == 4 46 assert mat[3, 2] == 7 47 assert struct.unpack_from('f', mat, (3 * 4 + 2) * 4) == (7, ) 48 assert struct.unpack_from('f', mat, (2 * 4 + 3) * 4) == (4, ) 49 50 mat2 = np.array(mat, copy=False) 51 assert mat2.shape == (5, 4) 52 assert abs(mat2).sum() == 11 53 assert mat2[2, 3] == 4 and mat2[3, 2] == 7 54 mat2[2, 3] = 5 55 assert mat2[2, 3] == 5 56 57 cstats = ConstructorStats.get(m.Matrix) 58 assert cstats.alive() == 1 59 del mat 60 pytest.gc_collect() 61 assert cstats.alive() == 1 62 del mat2 # holds a mat reference 63 pytest.gc_collect() 64 assert cstats.alive() == 0 65 assert cstats.values() == ["5x4 matrix"] 66 assert cstats.copy_constructions == 0 67 # assert cstats.move_constructions >= 0 # Don't invoke any 68 assert cstats.copy_assignments == 0 69 assert cstats.move_assignments == 0 70 71 72@pytest.unsupported_on_pypy 73def test_inherited_protocol(): 74 """SquareMatrix is derived from Matrix and inherits the buffer protocol""" 75 76 matrix = m.SquareMatrix(5) 77 assert memoryview(matrix).shape == (5, 5) 78 assert np.asarray(matrix).shape == (5, 5) 79 80 81@pytest.unsupported_on_pypy 82def test_pointer_to_member_fn(): 83 for cls in [m.Buffer, m.ConstBuffer, m.DerivedBuffer]: 84 buf = cls() 85 buf.value = 0x12345678 86 value = struct.unpack('i', bytearray(buf))[0] 87 assert value == 0x12345678 88