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

83
84
85
    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)
86
87


88
@pytest.unsupported_on_pypy
89
90
91
92
@pytest.requires_numpy
def test_vector_buffer_numpy():
    a = np.array([1, 2, 3, 4], dtype=np.int32)
    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
98
    assert len(v) == 4
    assert v[2] == 3
99
100
    ma = np.asarray(v)
    ma[2] = 5
101
102
    assert v[2] == 5

103
    v = m.VectorInt(a[:, 1])
104
105
106
    assert len(v) == 3
    assert v[2] == 10

107
    v = m.get_vectorstruct()
108
    assert v[0].x == 5
109
110
    ma = np.asarray(v)
    ma[1]['x'] = 99
111
112
    assert v[1].x == 99

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

117

Dean Moldovan's avatar
Dean Moldovan committed
118
def test_vector_bool():
119
120
121
    import pybind11_cross_module_tests as cm

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

128

129
130
131
132
133
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
134

135
136
137
138
    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
139
140


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

154
155
156
    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
157
158
159


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

165
    umc = m.UnorderedMapStringDoubleConst()
Sergey Lyskov's avatar
Sergey Lyskov committed
166
167
168
169
    umc['a'] = 11
    umc['b'] = 21.5

    str(umc)
170

171

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

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

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

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

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

    vsum = 0
    for k, v in mnc.items():
198
        assert v.value == 10 * k
199
200
        vsum += v.value

201
202
    assert vsum == 150

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

    vsum = 0
    for k, v in mnc.items():
210
        assert v.value == 10 * k
211
212
        vsum += v.value

213
    assert vsum == 150
214

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

253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273

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