test_stl_binders.py 6.8 KB
Newer Older
1
2
import pytest
import sys
3
from pybind11_tests import stl_binders as m
4
5
6
7
8

with pytest.suppress(ImportError):
    import numpy as np


Dean Moldovan's avatar
Dean Moldovan committed
9
def test_vector_int():
10
    v_int = m.VectorInt([0, 0])
Dean Moldovan's avatar
Dean Moldovan committed
11
12
13
    assert len(v_int) == 2
    assert bool(v_int) is True

14
15
16
17
    # test construction from a generator
    v_int1 = m.VectorInt(x for x in range(5))
    assert v_int1 == m.VectorInt([0, 1, 2, 3, 4])

18
    v_int2 = m.VectorInt([0, 0])
Dean Moldovan's avatar
Dean Moldovan committed
19
20
21
22
23
24
25
26
    assert v_int == v_int2
    v_int2[1] = 1
    assert v_int != v_int2

    v_int2.append(2)
    v_int2.insert(0, 1)
    v_int2.insert(0, 2)
    v_int2.insert(0, 3)
27
    v_int2.insert(6, 3)
Dean Moldovan's avatar
Dean Moldovan committed
28
    assert str(v_int2) == "VectorInt[3, 2, 1, 0, 1, 2, 3]"
29
30
    with pytest.raises(IndexError):
        v_int2.insert(8, 4)
Dean Moldovan's avatar
Dean Moldovan committed
31
32
33

    v_int.append(99)
    v_int2[2:-2] = v_int
34
    assert v_int2 == m.VectorInt([3, 2, 0, 0, 99, 2, 3])
Dean Moldovan's avatar
Dean Moldovan committed
35
    del v_int2[1:3]
36
    assert v_int2 == m.VectorInt([3, 0, 99, 2, 3])
Dean Moldovan's avatar
Dean Moldovan committed
37
    del v_int2[0]
38
    assert v_int2 == m.VectorInt([0, 99, 2, 3])
Dean Moldovan's avatar
Dean Moldovan committed
39

40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
    v_int2.extend(m.VectorInt([4, 5]))
    assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5])

    v_int2.extend([6, 7])
    assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5, 6, 7])

    # test error handling, and that the vector is unchanged
    with pytest.raises(RuntimeError):
        v_int2.extend([8, 'a'])

    assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5, 6, 7])

    # test extending from a generator
    v_int2.extend(x for x in range(5))
    assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4])

56
57
58
59
60
61
62
63
64
65
    # test negative indexing
    assert v_int2[-1] == 4

    # insert with negative index
    v_int2.insert(-1, 88)
    assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 88, 4])

    # delete negative index
    del v_int2[-1]
    assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 88])
Dean Moldovan's avatar
Dean Moldovan committed
66

67
68
69
    v_int2.clear()
    assert len(v_int2) == 0

70

71
# related to the PyPy's buffer protocol.
72
73
74
@pytest.unsupported_on_pypy
def test_vector_buffer():
    b = bytearray([1, 2, 3, 4])
75
    v = m.VectorUChar(b)
76
77
    assert v[1] == 2
    v[2] = 5
78
    mv = memoryview(v)  # We expose the buffer interface
79
    if sys.version_info.major > 2:
80
81
        assert mv[2] == 5
        mv[2] = 6
82
    else:
83
84
        assert mv[2] == '\x05'
        mv[2] = '\x06'
85
86
    assert v[2] == 6

87
88
89
    with pytest.raises(RuntimeError) as excinfo:
        m.create_undeclstruct()  # Undeclared struct contents, no buffer interface
    assert "NumPy type info missing for " in str(excinfo.value)
90
91


92
@pytest.unsupported_on_pypy
93
94
95
96
@pytest.requires_numpy
def test_vector_buffer_numpy():
    a = np.array([1, 2, 3, 4], dtype=np.int32)
    with pytest.raises(TypeError):
97
        m.VectorInt(a)
98
99

    a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], dtype=np.uintc)
100
    v = m.VectorInt(a[0, :])
101
102
    assert len(v) == 4
    assert v[2] == 3
103
104
    ma = np.asarray(v)
    ma[2] = 5
105
106
    assert v[2] == 5

107
    v = m.VectorInt(a[:, 1])
108
109
110
    assert len(v) == 3
    assert v[2] == 10

111
    v = m.get_vectorstruct()
112
    assert v[0].x == 5
113
114
    ma = np.asarray(v)
    ma[1]['x'] = 99
115
116
    assert v[1].x == 99

117
118
    v = m.VectorStruct(np.zeros(3, dtype=np.dtype([('w', 'bool'), ('x', 'I'),
                                                   ('y', 'float64'), ('z', 'bool')], align=True)))
119
120
    assert len(v) == 3

121

Dean Moldovan's avatar
Dean Moldovan committed
122
def test_vector_bool():
123
124
125
    import pybind11_cross_module_tests as cm

    vv_c = cm.VectorBool()
Dean Moldovan's avatar
Dean Moldovan committed
126
127
128
129
130
    for i in range(10):
        vv_c.append(i % 2 == 0)
    for i in range(10):
        assert vv_c[i] == (i % 2 == 0)
    assert str(vv_c) == "VectorBool[1, 0, 1, 0, 1, 0, 1, 0, 1, 0]"
Sergey Lyskov's avatar
Sergey Lyskov committed
131

132

133
134
135
136
137
def test_vector_custom():
    v_a = m.VectorEl()
    v_a.append(m.El(1))
    v_a.append(m.El(2))
    assert str(v_a) == "VectorEl[El{1}, El{2}]"
Sergey Lyskov's avatar
Sergey Lyskov committed
138

139
140
141
142
    vv_a = m.VectorVectorEl()
    vv_a.append(v_a)
    vv_b = vv_a[0]
    assert str(vv_b) == "VectorEl[El{1}, El{2}]"
Sergey Lyskov's avatar
Sergey Lyskov committed
143
144


145
146
147
148
149
150
151
152
153
154
def test_map_string_double():
    mm = m.MapStringDouble()
    mm['a'] = 1
    mm['b'] = 2.5

    assert list(mm) == ['a', 'b']
    assert list(mm.items()) == [('a', 1), ('b', 2.5)]
    assert str(mm) == "MapStringDouble{a: 1, b: 2.5}"

    um = m.UnorderedMapStringDouble()
Sergey Lyskov's avatar
Sergey Lyskov committed
155
156
157
    um['ua'] = 1.1
    um['ub'] = 2.6

158
159
160
    assert sorted(list(um)) == ['ua', 'ub']
    assert sorted(list(um.items())) == [('ua', 1.1), ('ub', 2.6)]
    assert "UnorderedMapStringDouble" in str(um)
Sergey Lyskov's avatar
Sergey Lyskov committed
161
162
163


def test_map_string_double_const():
164
    mc = m.MapStringDoubleConst()
Sergey Lyskov's avatar
Sergey Lyskov committed
165
166
167
168
    mc['a'] = 10
    mc['b'] = 20.5
    assert str(mc) == "MapStringDoubleConst{a: 10, b: 20.5}"

169
    umc = m.UnorderedMapStringDoubleConst()
Sergey Lyskov's avatar
Sergey Lyskov committed
170
171
172
173
    umc['a'] = 11
    umc['b'] = 21.5

    str(umc)
174

175

176
177
178
def test_noncopyable_containers():
    # std::vector
    vnc = m.get_vnc(5)
179
    for i in range(0, 5):
180
181
182
183
        assert vnc[i].value == i + 1

    for i, j in enumerate(vnc, start=1):
        assert j.value == i
184

185
186
    # std::deque
    dnc = m.get_dnc(5)
187
    for i in range(0, 5):
188
        assert dnc[i].value == i + 1
189
190
191
192
193
194

    i = 1
    for j in dnc:
        assert(j.value == i)
        i += 1

195
196
    # std::map
    mnc = m.get_mnc(5)
197
    for i in range(1, 6):
198
        assert mnc[i].value == 10 * i
199
200
201

    vsum = 0
    for k, v in mnc.items():
202
        assert v.value == 10 * k
203
204
        vsum += v.value

205
206
    assert vsum == 150

207
208
    # std::unordered_map
    mnc = m.get_umnc(5)
209
    for i in range(1, 6):
210
        assert mnc[i].value == 10 * i
211
212
213

    vsum = 0
    for k, v in mnc.items():
214
        assert v.value == 10 * k
215
216
        vsum += v.value

217
    assert vsum == 150
218

219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
    # nested std::map<std::vector>
    nvnc = m.get_nvnc(5)
    for i in range(1, 6):
        for j in range(0, 5):
            assert nvnc[i][j].value == j + 1

    for k, v in nvnc.items():
        for i, j in enumerate(v, start=1):
            assert j.value == i

    # nested std::map<std::map>
    nmnc = m.get_nmnc(5)
    for i in range(1, 6):
        for j in range(10, 60, 10):
            assert nmnc[i][j].value == 10 * j

    vsum = 0
    for k_o, v_o in nmnc.items():
        for k_i, v_i in v_o.items():
            assert v_i.value == 10 * k_i
            vsum += v_i.value

    assert vsum == 7500

    # nested std::unordered_map<std::unordered_map>
    numnc = m.get_numnc(5)
    for i in range(1, 6):
        for j in range(10, 60, 10):
            assert numnc[i][j].value == 10 * j

    vsum = 0
    for k_o, v_o in numnc.items():
        for k_i, v_i in v_o.items():
            assert v_i.value == 10 * k_i
            vsum += v_i.value

    assert vsum == 7500

257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277

def test_map_delitem():
    mm = m.MapStringDouble()
    mm['a'] = 1
    mm['b'] = 2.5

    assert list(mm) == ['a', 'b']
    assert list(mm.items()) == [('a', 1), ('b', 2.5)]
    del mm['a']
    assert list(mm) == ['b']
    assert list(mm.items()) == [('b', 2.5)]

    um = m.UnorderedMapStringDouble()
    um['ua'] = 1.1
    um['ub'] = 2.6

    assert sorted(list(um)) == ['ua', 'ub']
    assert sorted(list(um.items())) == [('ua', 1.1), ('ub', 2.6)]
    del um['ua']
    assert sorted(list(um)) == ['ub']
    assert sorted(list(um.items())) == [('ub', 2.6)]