Bruce Merry | fe0cf8b | 2017-05-17 10:52:33 +0200 | [diff] [blame] | 1 | import struct |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 2 | import pytest |
Jason Rhinelander | 391c754 | 2017-07-25 16:47:36 -0400 | [diff] [blame] | 3 | from pybind11_tests import buffers as m |
| 4 | from pybind11_tests import ConstructorStats |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 5 | |
Dean Moldovan | d47febc | 2017-03-10 15:42:42 +0100 | [diff] [blame] | 6 | pytestmark = pytest.requires_numpy |
| 7 | |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 8 | with pytest.suppress(ImportError): |
| 9 | import numpy as np |
| 10 | |
| 11 | |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 12 | def test_from_python(): |
| 13 | with pytest.raises(RuntimeError) as excinfo: |
Jason Rhinelander | 391c754 | 2017-07-25 16:47:36 -0400 | [diff] [blame] | 14 | m.Matrix(np.array([1, 2, 3])) # trying to assign a 1D array |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 15 | assert str(excinfo.value) == "Incompatible buffer format!" |
| 16 | |
| 17 | m3 = np.array([[1, 2, 3], [4, 5, 6]]).astype(np.float32) |
Jason Rhinelander | 391c754 | 2017-07-25 16:47:36 -0400 | [diff] [blame] | 18 | m4 = m.Matrix(m3) |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 19 | |
| 20 | for i in range(m4.rows()): |
| 21 | for j in range(m4.cols()): |
| 22 | assert m3[i, j] == m4[i, j] |
| 23 | |
Jason Rhinelander | 391c754 | 2017-07-25 16:47:36 -0400 | [diff] [blame] | 24 | cstats = ConstructorStats.get(m.Matrix) |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 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 |
Wenzel Jakob | 1d1f81b | 2016-12-16 15:00:46 +0100 | [diff] [blame] | 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 |
Wenzel Jakob | 1d1f81b | 2016-12-16 15:00:46 +0100 | [diff] [blame] | 38 | def test_to_python(): |
Ansgar Burchardt | a22dd2d | 2017-09-21 23:07:48 +0200 | [diff] [blame] | 39 | mat = m.Matrix(5, 4) |
| 40 | assert memoryview(mat).shape == (5, 4) |
Wenzel Jakob | 1d1f81b | 2016-12-16 15:00:46 +0100 | [diff] [blame] | 41 | |
Jason Rhinelander | 391c754 | 2017-07-25 16:47:36 -0400 | [diff] [blame] | 42 | assert mat[2, 3] == 0 |
Ansgar Burchardt | a22dd2d | 2017-09-21 23:07:48 +0200 | [diff] [blame] | 43 | mat[2, 3] = 4.0 |
| 44 | mat[3, 2] = 7.0 |
Jason Rhinelander | 391c754 | 2017-07-25 16:47:36 -0400 | [diff] [blame] | 45 | assert mat[2, 3] == 4 |
Ansgar Burchardt | a22dd2d | 2017-09-21 23:07:48 +0200 | [diff] [blame] | 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, ) |
Wenzel Jakob | 1d1f81b | 2016-12-16 15:00:46 +0100 | [diff] [blame] | 49 | |
Jason Rhinelander | 391c754 | 2017-07-25 16:47:36 -0400 | [diff] [blame] | 50 | mat2 = np.array(mat, copy=False) |
Ansgar Burchardt | a22dd2d | 2017-09-21 23:07:48 +0200 | [diff] [blame] | 51 | assert mat2.shape == (5, 4) |
| 52 | assert abs(mat2).sum() == 11 |
| 53 | assert mat2[2, 3] == 4 and mat2[3, 2] == 7 |
Jason Rhinelander | 391c754 | 2017-07-25 16:47:36 -0400 | [diff] [blame] | 54 | mat2[2, 3] = 5 |
| 55 | assert mat2[2, 3] == 5 |
Wenzel Jakob | 1d1f81b | 2016-12-16 15:00:46 +0100 | [diff] [blame] | 56 | |
Jason Rhinelander | 391c754 | 2017-07-25 16:47:36 -0400 | [diff] [blame] | 57 | cstats = ConstructorStats.get(m.Matrix) |
Wenzel Jakob | 1d1f81b | 2016-12-16 15:00:46 +0100 | [diff] [blame] | 58 | assert cstats.alive() == 1 |
Jason Rhinelander | 391c754 | 2017-07-25 16:47:36 -0400 | [diff] [blame] | 59 | del mat |
Wenzel Jakob | 1d1f81b | 2016-12-16 15:00:46 +0100 | [diff] [blame] | 60 | pytest.gc_collect() |
| 61 | assert cstats.alive() == 1 |
Jason Rhinelander | 391c754 | 2017-07-25 16:47:36 -0400 | [diff] [blame] | 62 | del mat2 # holds a mat reference |
Wenzel Jakob | 1d1f81b | 2016-12-16 15:00:46 +0100 | [diff] [blame] | 63 | pytest.gc_collect() |
| 64 | assert cstats.alive() == 0 |
Ansgar Burchardt | a22dd2d | 2017-09-21 23:07:48 +0200 | [diff] [blame] | 65 | assert cstats.values() == ["5x4 matrix"] |
Wenzel Jakob | 1d1f81b | 2016-12-16 15:00:46 +0100 | [diff] [blame] | 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 |
Bruce Merry | fe0cf8b | 2017-05-17 10:52:33 +0200 | [diff] [blame] | 70 | |
| 71 | |
| 72 | @pytest.unsupported_on_pypy |
Dean Moldovan | 427e4af | 2017-05-28 16:35:02 +0200 | [diff] [blame] | 73 | def test_inherited_protocol(): |
| 74 | """SquareMatrix is derived from Matrix and inherits the buffer protocol""" |
Dean Moldovan | 427e4af | 2017-05-28 16:35:02 +0200 | [diff] [blame] | 75 | |
Jason Rhinelander | 391c754 | 2017-07-25 16:47:36 -0400 | [diff] [blame] | 76 | matrix = m.SquareMatrix(5) |
Dean Moldovan | 427e4af | 2017-05-28 16:35:02 +0200 | [diff] [blame] | 77 | assert memoryview(matrix).shape == (5, 5) |
| 78 | assert np.asarray(matrix).shape == (5, 5) |
| 79 | |
| 80 | |
| 81 | @pytest.unsupported_on_pypy |
Jason Rhinelander | 391c754 | 2017-07-25 16:47:36 -0400 | [diff] [blame] | 82 | def test_pointer_to_member_fn(): |
| 83 | for cls in [m.Buffer, m.ConstBuffer, m.DerivedBuffer]: |
Bruce Merry | fe0cf8b | 2017-05-17 10:52:33 +0200 | [diff] [blame] | 84 | buf = cls() |
| 85 | buf.value = 0x12345678 |
| 86 | value = struct.unpack('i', bytearray(buf))[0] |
| 87 | assert value == 0x12345678 |