test_stl_binders.py revision 14299
1import pytest 2import sys 3from pybind11_tests import stl_binders as m 4 5with pytest.suppress(ImportError): 6 import numpy as np 7 8 9def test_vector_int(): 10 v_int = m.VectorInt([0, 0]) 11 assert len(v_int) == 2 12 assert bool(v_int) is True 13 14 # test construction from a generator 15 v_int1 = m.VectorInt(x for x in range(5)) 16 assert v_int1 == m.VectorInt([0, 1, 2, 3, 4]) 17 18 v_int2 = m.VectorInt([0, 0]) 19 assert v_int == v_int2 20 v_int2[1] = 1 21 assert v_int != v_int2 22 23 v_int2.append(2) 24 v_int2.insert(0, 1) 25 v_int2.insert(0, 2) 26 v_int2.insert(0, 3) 27 v_int2.insert(6, 3) 28 assert str(v_int2) == "VectorInt[3, 2, 1, 0, 1, 2, 3]" 29 with pytest.raises(IndexError): 30 v_int2.insert(8, 4) 31 32 v_int.append(99) 33 v_int2[2:-2] = v_int 34 assert v_int2 == m.VectorInt([3, 2, 0, 0, 99, 2, 3]) 35 del v_int2[1:3] 36 assert v_int2 == m.VectorInt([3, 0, 99, 2, 3]) 37 del v_int2[0] 38 assert v_int2 == m.VectorInt([0, 99, 2, 3]) 39 40 v_int2.extend(m.VectorInt([4, 5])) 41 assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5]) 42 43 v_int2.extend([6, 7]) 44 assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5, 6, 7]) 45 46 # test error handling, and that the vector is unchanged 47 with pytest.raises(RuntimeError): 48 v_int2.extend([8, 'a']) 49 50 assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5, 6, 7]) 51 52 # test extending from a generator 53 v_int2.extend(x for x in range(5)) 54 assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4]) 55 56 # test negative indexing 57 assert v_int2[-1] == 4 58 59 # insert with negative index 60 v_int2.insert(-1, 88) 61 assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 88, 4]) 62 63 # delete negative index 64 del v_int2[-1] 65 assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 88]) 66 67# related to the PyPy's buffer protocol. 68@pytest.unsupported_on_pypy 69def test_vector_buffer(): 70 b = bytearray([1, 2, 3, 4]) 71 v = m.VectorUChar(b) 72 assert v[1] == 2 73 v[2] = 5 74 mv = memoryview(v) # We expose the buffer interface 75 if sys.version_info.major > 2: 76 assert mv[2] == 5 77 mv[2] = 6 78 else: 79 assert mv[2] == '\x05' 80 mv[2] = '\x06' 81 assert v[2] == 6 82 83 with pytest.raises(RuntimeError) as excinfo: 84 m.create_undeclstruct() # Undeclared struct contents, no buffer interface 85 assert "NumPy type info missing for " in str(excinfo.value) 86 87 88@pytest.unsupported_on_pypy 89@pytest.requires_numpy 90def test_vector_buffer_numpy(): 91 a = np.array([1, 2, 3, 4], dtype=np.int32) 92 with pytest.raises(TypeError): 93 m.VectorInt(a) 94 95 a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], dtype=np.uintc) 96 v = m.VectorInt(a[0, :]) 97 assert len(v) == 4 98 assert v[2] == 3 99 ma = np.asarray(v) 100 ma[2] = 5 101 assert v[2] == 5 102 103 v = m.VectorInt(a[:, 1]) 104 assert len(v) == 3 105 assert v[2] == 10 106 107 v = m.get_vectorstruct() 108 assert v[0].x == 5 109 ma = np.asarray(v) 110 ma[1]['x'] = 99 111 assert v[1].x == 99 112 113 v = m.VectorStruct(np.zeros(3, dtype=np.dtype([('w', 'bool'), ('x', 'I'), 114 ('y', 'float64'), ('z', 'bool')], align=True))) 115 assert len(v) == 3 116 117 118def test_vector_bool(): 119 import pybind11_cross_module_tests as cm 120 121 vv_c = cm.VectorBool() 122 for i in range(10): 123 vv_c.append(i % 2 == 0) 124 for i in range(10): 125 assert vv_c[i] == (i % 2 == 0) 126 assert str(vv_c) == "VectorBool[1, 0, 1, 0, 1, 0, 1, 0, 1, 0]" 127 128 129def test_vector_custom(): 130 v_a = m.VectorEl() 131 v_a.append(m.El(1)) 132 v_a.append(m.El(2)) 133 assert str(v_a) == "VectorEl[El{1}, El{2}]" 134 135 vv_a = m.VectorVectorEl() 136 vv_a.append(v_a) 137 vv_b = vv_a[0] 138 assert str(vv_b) == "VectorEl[El{1}, El{2}]" 139 140 141def test_map_string_double(): 142 mm = m.MapStringDouble() 143 mm['a'] = 1 144 mm['b'] = 2.5 145 146 assert list(mm) == ['a', 'b'] 147 assert list(mm.items()) == [('a', 1), ('b', 2.5)] 148 assert str(mm) == "MapStringDouble{a: 1, b: 2.5}" 149 150 um = m.UnorderedMapStringDouble() 151 um['ua'] = 1.1 152 um['ub'] = 2.6 153 154 assert sorted(list(um)) == ['ua', 'ub'] 155 assert sorted(list(um.items())) == [('ua', 1.1), ('ub', 2.6)] 156 assert "UnorderedMapStringDouble" in str(um) 157 158 159def test_map_string_double_const(): 160 mc = m.MapStringDoubleConst() 161 mc['a'] = 10 162 mc['b'] = 20.5 163 assert str(mc) == "MapStringDoubleConst{a: 10, b: 20.5}" 164 165 umc = m.UnorderedMapStringDoubleConst() 166 umc['a'] = 11 167 umc['b'] = 21.5 168 169 str(umc) 170 171 172def test_noncopyable_containers(): 173 # std::vector 174 vnc = m.get_vnc(5) 175 for i in range(0, 5): 176 assert vnc[i].value == i + 1 177 178 for i, j in enumerate(vnc, start=1): 179 assert j.value == i 180 181 # std::deque 182 dnc = m.get_dnc(5) 183 for i in range(0, 5): 184 assert dnc[i].value == i + 1 185 186 i = 1 187 for j in dnc: 188 assert(j.value == i) 189 i += 1 190 191 # std::map 192 mnc = m.get_mnc(5) 193 for i in range(1, 6): 194 assert mnc[i].value == 10 * i 195 196 vsum = 0 197 for k, v in mnc.items(): 198 assert v.value == 10 * k 199 vsum += v.value 200 201 assert vsum == 150 202 203 # std::unordered_map 204 mnc = m.get_umnc(5) 205 for i in range(1, 6): 206 assert mnc[i].value == 10 * i 207 208 vsum = 0 209 for k, v in mnc.items(): 210 assert v.value == 10 * k 211 vsum += v.value 212 213 assert vsum == 150 214 215 216def test_map_delitem(): 217 mm = m.MapStringDouble() 218 mm['a'] = 1 219 mm['b'] = 2.5 220 221 assert list(mm) == ['a', 'b'] 222 assert list(mm.items()) == [('a', 1), ('b', 2.5)] 223 del mm['a'] 224 assert list(mm) == ['b'] 225 assert list(mm.items()) == [('b', 2.5)] 226 227 um = m.UnorderedMapStringDouble() 228 um['ua'] = 1.1 229 um['ub'] = 2.6 230 231 assert sorted(list(um)) == ['ua', 'ub'] 232 assert sorted(list(um.items())) == [('ua', 1.1), ('ub', 2.6)] 233 del um['ua'] 234 assert sorted(list(um)) == ['ub'] 235 assert sorted(list(um.items())) == [('ub', 2.6)] 236