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

86
87
88
    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)
89
90


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

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

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

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

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

120

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

    vv_c = cm.VectorBool()
Dean Moldovan's avatar
Dean Moldovan committed
125
126
127
128
129
    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
130

131

132
133
134
135
136
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
137

138
139
140
141
    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
142
143


144
145
146
147
148
149
150
151
152
153
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
154
155
156
    um['ua'] = 1.1
    um['ub'] = 2.6

157
158
159
    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
160
161
162


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

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

    str(umc)
173

174

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

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

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

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

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

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

204
205
    assert vsum == 150

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

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

216
    assert vsum == 150
217

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
    # 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

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

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)]