μHAL (v2.8.17)
Part of the IPbus software repository
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
test_buffers.py
Go to the documentation of this file.
1# -*- coding: utf-8 -*-
2import ctypes
3import io
4import struct
5
6import pytest
7
8import env
9from pybind11_tests import ConstructorStats
10from pybind11_tests import buffers as m
11
12np = pytest.importorskip("numpy")
13
14
16 with pytest.raises(RuntimeError) as excinfo:
17 m.Matrix(np.array([1, 2, 3])) # trying to assign a 1D array
18 assert str(excinfo.value) == "Incompatible buffer format!"
19
20 m3 = np.array([[1, 2, 3], [4, 5, 6]]).astype(np.float32)
21 m4 = m.Matrix(m3)
22
23 for i in range(m4.rows()):
24 for j in range(m4.cols()):
25 assert m3[i, j] == m4[i, j]
26
27 cstats = ConstructorStats.get(m.Matrix)
28 assert cstats.alive() == 1
29 del m3, m4
30 assert cstats.alive() == 0
31 assert cstats.values() == ["2x3 matrix"]
32 assert cstats.copy_constructions == 0
33 # assert cstats.move_constructions >= 0 # Don't invoke any
34 assert cstats.copy_assignments == 0
35 assert cstats.move_assignments == 0
36
37
38# https://foss.heptapod.net/pypy/pypy/-/issues/2444
39# TODO: fix on recent PyPy
40@pytest.mark.xfail(
41 env.PYPY, reason="PyPy 7.3.7 doesn't clear this anymore", strict=False
42)
44 mat = m.Matrix(5, 4)
45 assert memoryview(mat).shape == (5, 4)
46
47 assert mat[2, 3] == 0
48 mat[2, 3] = 4.0
49 mat[3, 2] = 7.0
50 assert mat[2, 3] == 4
51 assert mat[3, 2] == 7
52 assert struct.unpack_from("f", mat, (3 * 4 + 2) * 4) == (7,)
53 assert struct.unpack_from("f", mat, (2 * 4 + 3) * 4) == (4,)
54
55 mat2 = np.array(mat, copy=False)
56 assert mat2.shape == (5, 4)
57 assert abs(mat2).sum() == 11
58 assert mat2[2, 3] == 4 and mat2[3, 2] == 7
59 mat2[2, 3] = 5
60 assert mat2[2, 3] == 5
61
62 cstats = ConstructorStats.get(m.Matrix)
63 assert cstats.alive() == 1
64 del mat
65 pytest.gc_collect()
66 assert cstats.alive() == 1
67 del mat2 # holds a mat reference
68 pytest.gc_collect()
69 assert cstats.alive() == 0
70 assert cstats.values() == ["5x4 matrix"]
71 assert cstats.copy_constructions == 0
72 # assert cstats.move_constructions >= 0 # Don't invoke any
73 assert cstats.copy_assignments == 0
74 assert cstats.move_assignments == 0
75
76
78 """SquareMatrix is derived from Matrix and inherits the buffer protocol"""
79
80 matrix = m.SquareMatrix(5)
81 assert memoryview(matrix).shape == (5, 5)
82 assert np.asarray(matrix).shape == (5, 5)
83
84
86 for cls in [m.Buffer, m.ConstBuffer, m.DerivedBuffer]:
87 buf = cls()
88 buf.value = 0x12345678
89 value = struct.unpack("i", bytearray(buf))[0]
90 assert value == 0x12345678
91
92
94 buf = m.BufferReadOnly(0x64)
95 view = memoryview(buf)
96 assert view[0] == b"d" if env.PY2 else 0x64
97 assert view.readonly
98 with pytest.raises(TypeError):
99 view[0] = b"\0" if env.PY2 else 0
100
101
103 buf = m.BufferReadOnlySelect()
104
105 memoryview(buf)[0] = b"d" if env.PY2 else 0x64
106 assert buf.value == 0x64
107
108 io.BytesIO(b"A").readinto(buf)
109 assert buf.value == ord(b"A")
110
111 buf.readonly = True
112 with pytest.raises(TypeError):
113 memoryview(buf)[0] = b"\0" if env.PY2 else 0
114 with pytest.raises(TypeError):
115 io.BytesIO(b"1").readinto(buf)
116
117
119 char1d = (ctypes.c_char * 10)()
120 int1d = (ctypes.c_int * 15)()
121 long1d = (ctypes.c_long * 7)()
122
123 for carray in (char1d, int1d, long1d):
124 info = m.get_buffer_info(carray)
125 assert info.itemsize == ctypes.sizeof(carray._type_)
126 assert info.size == len(carray)
127 assert info.ndim == 1
128 assert info.shape == [info.size]
129 assert info.strides == [info.itemsize]
130 assert not info.readonly
131
132
134 char2d = ((ctypes.c_char * 10) * 4)()
135 int2d = ((ctypes.c_int * 15) * 3)()
136 long2d = ((ctypes.c_long * 7) * 2)()
137
138 for carray in (char2d, int2d, long2d):
139 info = m.get_buffer_info(carray)
140 assert info.itemsize == ctypes.sizeof(carray[0]._type_)
141 assert info.size == len(carray) * len(carray[0])
142 assert info.ndim == 2
143 assert info.shape == [len(carray), len(carray[0])]
144 assert info.strides == [info.itemsize * len(carray[0]), info.itemsize]
145 assert not info.readonly
146
147
148@pytest.mark.skipif(
149 "env.PYPY and env.PY2", reason="PyPy2 bytes buffer not reported as readonly"
150)
152 test_pystr = b"0123456789"
153 for pyarray in (test_pystr, bytearray(test_pystr)):
154 pyinfo = m.get_buffer_info(pyarray)
155
156 if pyinfo.readonly:
157 cbytes = (ctypes.c_char * len(pyarray)).from_buffer_copy(pyarray)
158 cinfo = m.get_buffer_info(cbytes)
159 else:
160 cbytes = (ctypes.c_char * len(pyarray)).from_buffer(pyarray)
161 cinfo = m.get_buffer_info(cbytes)
162
163 assert cinfo.size == pyinfo.size
164 assert cinfo.ndim == pyinfo.ndim
165 assert cinfo.shape == pyinfo.shape
166 assert cinfo.strides == pyinfo.strides
167 assert not cinfo.readonly
static ConstructorStats & get(std::type_index type)
Definition: pytypes.h:1200
size_t len(handle h)
Get the length of a Python object.
Definition: pytypes.h:2002
def test_from_python()
Definition: test_buffers.py:15
def test_selective_readonly_buffer()
def test_readonly_buffer()
Definition: test_buffers.py:93
def test_pointer_to_member_fn()
Definition: test_buffers.py:85
def test_ctypes_array_2d()
def test_inherited_protocol()
Definition: test_buffers.py:77
def test_to_python()
Definition: test_buffers.py:43
def test_ctypes_from_buffer()
def test_ctypes_array_1d()
std::string abs(const Vector2 &)