1 from __future__
import annotations
10 from pybind11_tests
import ConstructorStats
11 from pybind11_tests
import buffers
as m
13 np = pytest.importorskip(
"numpy")
15 if m.long_double_and_double_have_same_size:
22 np_float128 =
getattr(np, *[
"float128"] * 2)
23 np_complex256 =
getattr(np, *[
"complex256"] * 2)
25 CPP_NAME_FORMAT_NP_DTYPE_TABLE = [
26 (
"PyObject *",
"O", object),
27 (
"bool",
"?", np.bool_),
28 (
"std::int8_t",
"b", np.int8),
29 (
"std::uint8_t",
"B", np.uint8),
30 (
"std::int16_t",
"h", np.int16),
31 (
"std::uint16_t",
"H", np.uint16),
32 (
"std::int32_t",
"i", np.int32),
33 (
"std::uint32_t",
"I", np.uint32),
34 (
"std::int64_t",
"q", np.int64),
35 (
"std::uint64_t",
"Q", np.uint64),
36 (
"float",
"f", np.float32),
37 (
"double",
"d", np.float64),
38 (
"long double",
"g", np_float128),
39 (
"std::complex<float>",
"Zf", np.complex64),
40 (
"std::complex<double>",
"Zd", np.complex128),
41 (
"std::complex<long double>",
"Zg", np_complex256),
43 CPP_NAME_FORMAT_TABLE = [
45 for cpp_name, format, np_dtype
in CPP_NAME_FORMAT_NP_DTYPE_TABLE
46 if np_dtype
is not None
48 CPP_NAME_NP_DTYPE_TABLE = [
49 (cpp_name, np_dtype)
for cpp_name, _, np_dtype
in CPP_NAME_FORMAT_NP_DTYPE_TABLE
53 @pytest.mark.parametrize((
"cpp_name",
"np_dtype"), CPP_NAME_NP_DTYPE_TABLE)
57 f
"cpp_name=`{cpp_name}`: `long double` and `double` have same size."
60 pytest.skip(f
"np.{np_dtype} does not exist.")
61 np_array = np.array([], dtype=np_dtype)
62 for other_cpp_name, expected_format
in CPP_NAME_FORMAT_TABLE:
63 format, np_array_is_matching = m.format_descriptor_format_buffer_info_equiv(
64 other_cpp_name, np_array
66 assert format == expected_format
67 if other_cpp_name == cpp_name:
68 assert np_array_is_matching
70 assert not np_array_is_matching
74 with pytest.raises(RuntimeError)
as excinfo:
75 m.Matrix(np.array([1, 2, 3]))
76 assert str(excinfo.value) ==
"Incompatible buffer format!"
78 m3 = np.array([[1, 2, 3], [4, 5, 6]]).astype(np.float32)
81 for i
in range(m4.rows()):
82 for j
in range(m4.cols()):
83 assert m3[i, j] == m4[i, j]
86 assert cstats.alive() == 1
88 assert cstats.alive() == 0
89 assert cstats.values() == [
"2x3 matrix"]
90 assert cstats.copy_constructions == 0
92 assert cstats.copy_assignments == 0
93 assert cstats.move_assignments == 0
99 env.PYPY, reason=
"PyPy 7.3.7 doesn't clear this anymore", strict=
False
105 assert mat[2, 3] == 0
108 assert mat[2, 3] == 4
109 assert mat[3, 2] == 7
110 assert struct.unpack_from(
"f", mat, (3 * 4 + 2) * 4) == (7,)
111 assert struct.unpack_from(
"f", mat, (2 * 4 + 3) * 4) == (4,)
113 mat2 = np.array(mat, copy=
False)
114 assert mat2.shape == (5, 4)
115 assert abs(mat2).sum() == 11
116 assert mat2[2, 3] == 4
117 assert mat2[3, 2] == 7
119 assert mat2[2, 3] == 5
122 assert cstats.alive() == 1
125 assert cstats.alive() == 1
128 assert cstats.alive() == 0
129 assert cstats.values() == [
"5x4 matrix"]
130 assert cstats.copy_constructions == 0
132 assert cstats.copy_assignments == 0
133 assert cstats.move_assignments == 0
137 """SquareMatrix is derived from Matrix and inherits the buffer protocol"""
139 matrix = m.SquareMatrix(5)
141 assert np.asarray(matrix).shape == (5, 5)
145 for cls
in [m.Buffer, m.ConstBuffer, m.DerivedBuffer]:
147 buf.value = 0x12345678
148 value = struct.unpack(
"i",
bytearray(buf))[0]
149 assert value == 0x12345678
153 buf = m.BufferReadOnly(0x64)
155 assert view[0] == 0x64
157 with pytest.raises(TypeError):
162 buf = m.BufferReadOnlySelect()
165 assert buf.value == 0x64
167 io.BytesIO(b
"A").readinto(buf)
168 assert buf.value == ord(b
"A")
171 with pytest.raises(TypeError):
173 with pytest.raises(TypeError):
174 io.BytesIO(b
"1").readinto(buf)
178 char1d = (ctypes.c_char * 10)()
179 int1d = (ctypes.c_int * 15)()
180 long1d = (ctypes.c_long * 7)()
182 for carray
in (char1d, int1d, long1d):
183 info = m.get_buffer_info(carray)
184 assert info.itemsize == ctypes.sizeof(carray._type_)
185 assert info.size ==
len(carray)
186 assert info.ndim == 1
187 assert info.shape == [info.size]
188 assert info.strides == [info.itemsize]
189 assert not info.readonly
193 char2d = ((ctypes.c_char * 10) * 4)()
194 int2d = ((ctypes.c_int * 15) * 3)()
195 long2d = ((ctypes.c_long * 7) * 2)()
197 for carray
in (char2d, int2d, long2d):
198 info = m.get_buffer_info(carray)
199 assert info.itemsize == ctypes.sizeof(carray[0]._type_)
200 assert info.size ==
len(carray) *
len(carray[0])
201 assert info.ndim == 2
202 assert info.shape == [
len(carray),
len(carray[0])]
203 assert info.strides == [info.itemsize *
len(carray[0]), info.itemsize]
204 assert not info.readonly
208 test_pystr = b
"0123456789"
209 for pyarray
in (test_pystr,
bytearray(test_pystr)):
210 pyinfo = m.get_buffer_info(pyarray)
213 cbytes = (ctypes.c_char *
len(pyarray)).from_buffer_copy(pyarray)
214 cinfo = m.get_buffer_info(cbytes)
216 cbytes = (ctypes.c_char *
len(pyarray)).from_buffer(pyarray)
217 cinfo = m.get_buffer_info(cbytes)
219 assert cinfo.size == pyinfo.size
220 assert cinfo.ndim == pyinfo.ndim
221 assert cinfo.shape == pyinfo.shape
222 assert cinfo.strides == pyinfo.strides
223 assert not cinfo.readonly
228 m.get_buffer_info.__doc__.strip()
229 ==
"get_buffer_info(arg0: Buffer) -> pybind11_tests.buffers.buffer_info"