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