test_issues.py 6.9 KB
Newer Older
Dean Moldovan's avatar
Dean Moldovan committed
1
import pytest
2
from pybind11_tests import ConstructorStats
Dean Moldovan's avatar
Dean Moldovan committed
3
4


5
def test_regressions():
Dean Moldovan's avatar
Dean Moldovan committed
6
7
    from pybind11_tests.issues import print_cchar, print_char

8
9
10
11
    # #137: const char* isn't handled properly
    assert print_cchar("const char *") == "const char *"
    # #150: char bindings broken
    assert print_char("c") == "c"
Dean Moldovan's avatar
Dean Moldovan committed
12
13


14
def test_dispatch_issue(msg):
Dean Moldovan's avatar
Dean Moldovan committed
15
16
17
18
19
    """#159: virtual function dispatch has problems with similar-named functions"""
    from pybind11_tests.issues import DispatchIssue, dispatch_issue_go

    class PyClass1(DispatchIssue):
        def dispatch(self):
20
            return "Yay.."
Dean Moldovan's avatar
Dean Moldovan committed
21
22
23
24
25
26
27
28

    class PyClass2(DispatchIssue):
        def dispatch(self):
            with pytest.raises(RuntimeError) as excinfo:
                super(PyClass2, self).dispatch()
            assert msg(excinfo.value) == 'Tried to call pure virtual function "Base::dispatch"'

            p = PyClass1()
29
            return dispatch_issue_go(p)
Dean Moldovan's avatar
Dean Moldovan committed
30
31

    b = PyClass2()
32
    assert dispatch_issue_go(b) == "Yay.."
Dean Moldovan's avatar
Dean Moldovan committed
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56


def test_reference_wrapper():
    """#171: Can't return reference wrappers (or STL data structures containing them)"""
    from pybind11_tests.issues import Placeholder, return_vec_of_reference_wrapper

    assert str(return_vec_of_reference_wrapper(Placeholder(4))) == \
        "[Placeholder[1], Placeholder[2], Placeholder[3], Placeholder[4]]"


def test_iterator_passthrough():
    """#181: iterator passthrough did not compile"""
    from pybind11_tests.issues import iterator_passthrough

    assert list(iterator_passthrough(iter([3, 5, 7, 9, 11, 13, 15]))) == [3, 5, 7, 9, 11, 13, 15]


def test_shared_ptr_gc():
    """// #187: issue involving std::shared_ptr<> return value policy & garbage collection"""
    from pybind11_tests.issues import ElementList, ElementA

    el = ElementList()
    for i in range(10):
        el.add(ElementA(i))
Wenzel Jakob's avatar
Wenzel Jakob committed
57
    pytest.gc_collect()
Dean Moldovan's avatar
Dean Moldovan committed
58
59
60
61
    for i, v in enumerate(el.get()):
        assert i == v.value()


62
def test_no_id(msg):
63
    from pybind11_tests.issues import get_element, expect_float, expect_int
Dean Moldovan's avatar
Dean Moldovan committed
64
65

    with pytest.raises(TypeError) as excinfo:
66
        get_element(None)
Dean Moldovan's avatar
Dean Moldovan committed
67
    assert msg(excinfo.value) == """
68
        get_element(): incompatible function arguments. The following argument types are supported:
69
            1. (arg0: m.issues.ElementA) -> int
70
71

        Invoked with: None
Dean Moldovan's avatar
Dean Moldovan committed
72
73
74
75
76
    """

    with pytest.raises(TypeError) as excinfo:
        expect_int(5.2)
    assert msg(excinfo.value) == """
77
        expect_int(): incompatible function arguments. The following argument types are supported:
Dean Moldovan's avatar
Dean Moldovan committed
78
            1. (arg0: int) -> int
79
80

        Invoked with: 5.2
Dean Moldovan's avatar
Dean Moldovan committed
81
82
83
84
    """
    assert expect_float(12) == 12


85
def test_str_issue(msg):
Dean Moldovan's avatar
Dean Moldovan committed
86
87
88
    """Issue #283: __str__ called on uninitialized instance when constructor arguments invalid"""
    from pybind11_tests.issues import StrIssue

89
    assert str(StrIssue(3)) == "StrIssue[3]"
Dean Moldovan's avatar
Dean Moldovan committed
90
91
92
93

    with pytest.raises(TypeError) as excinfo:
        str(StrIssue("no", "such", "constructor"))
    assert msg(excinfo.value) == """
94
        __init__(): incompatible constructor arguments. The following argument types are supported:
Dean Moldovan's avatar
Dean Moldovan committed
95
96
            1. m.issues.StrIssue(arg0: int)
            2. m.issues.StrIssue()
97

98
        Invoked with: 'no', 'such', 'constructor'
Dean Moldovan's avatar
Dean Moldovan committed
99
100
101
    """


102
def test_nested():
Dean Moldovan's avatar
Dean Moldovan committed
103
    """ #328: first member in a class can't be used in operators"""
104
    from pybind11_tests.issues import NestA, NestB, NestC, get_NestA, get_NestB, get_NestC
Dean Moldovan's avatar
Dean Moldovan committed
105
106
107
108
109
110

    a = NestA()
    b = NestB()
    c = NestC()

    a += 10
111
    assert get_NestA(a) == 13
Dean Moldovan's avatar
Dean Moldovan committed
112
    b.a += 100
113
    assert get_NestA(b.a) == 103
Dean Moldovan's avatar
Dean Moldovan committed
114
    c.b.a += 1000
115
    assert get_NestA(c.b.a) == 1003
Dean Moldovan's avatar
Dean Moldovan committed
116
    b -= 1
117
    assert get_NestB(b) == 3
Dean Moldovan's avatar
Dean Moldovan committed
118
    c.b -= 3
119
    assert get_NestB(c.b) == 1
Dean Moldovan's avatar
Dean Moldovan committed
120
    c *= 7
121
    assert get_NestC(c) == 35
Dean Moldovan's avatar
Dean Moldovan committed
122
123
124
125
126
127
128
129
130
131

    abase = a.as_base()
    assert abase.value == -2
    a.as_base().value += 44
    assert abase.value == 42
    assert c.b.a.as_base().value == -2
    c.b.a.as_base().value += 44
    assert c.b.a.as_base().value == 42

    del c
Wenzel Jakob's avatar
Wenzel Jakob committed
132
    pytest.gc_collect()
Dean Moldovan's avatar
Dean Moldovan committed
133
    del a  # Should't delete while abase is still alive
Wenzel Jakob's avatar
Wenzel Jakob committed
134
    pytest.gc_collect()
Dean Moldovan's avatar
Dean Moldovan committed
135
136
137

    assert abase.value == 42
    del abase, b
Wenzel Jakob's avatar
Wenzel Jakob committed
138
    pytest.gc_collect()
139
140
141
142
143
144
145
146


def test_move_fallback():
    from pybind11_tests.issues import get_moveissue1, get_moveissue2
    m2 = get_moveissue2(2)
    assert m2.value == 2
    m1 = get_moveissue1(1)
    assert m1.value == 1
147

148

149
150
def test_override_ref():
    from pybind11_tests.issues import OverrideTest
151
    o = OverrideTest("asdf")
152

153
    # Not allowed (see associated .cpp comment)
154
155
    # i = o.str_ref()
    # assert o.str_ref() == "asdf"
156
    assert o.str_value() == "asdf"
157

158
    assert o.A_value().value == "hi"
159
    a = o.A_ref()
160
161
162
    assert a.value == "hi"
    a.value = "bye"
    assert a.value == "bye"
163

164

165
166
167
def test_operators_notimplemented(capture):
    from pybind11_tests.issues import OpTest1, OpTest2
    with capture:
168
169
170
171
172
173
174
175
176
177
178
        c1, c2 = OpTest1(), OpTest2()
        c1 + c1
        c2 + c2
        c2 + c1
        c1 + c2
    assert capture == """
        Add OpTest1 with OpTest1
        Add OpTest2 with OpTest2
        Add OpTest2 with OpTest1
        Add OpTest2 with OpTest1
    """
179

180

181
182
183
184
185
186
187
def test_iterator_rvpolicy():
    """ Issue 388: Can't make iterators via make_iterator() with different r/v policies """
    from pybind11_tests.issues import make_iterator_1
    from pybind11_tests.issues import make_iterator_2

    assert list(make_iterator_1()) == [1, 2, 3]
    assert list(make_iterator_2()) == [1, 2, 3]
188
    assert not isinstance(make_iterator_1(), type(make_iterator_2()))
189

190

191
192
193
194
def test_dupe_assignment():
    """ Issue 461: overwriting a class with a function """
    from pybind11_tests.issues import dupe_exception_failures
    assert dupe_exception_failures() == []
195
196
197
198
199
200
201
202
203
204
205
206
207


def test_enable_shared_from_this_with_reference_rvp():
    """ Issue #471: shared pointer instance not dellocated """
    from pybind11_tests import SharedParent, SharedChild

    parent = SharedParent()
    child = parent.get_child()

    cstats = ConstructorStats.get(SharedChild)
    assert cstats.alive() == 1
    del child, parent
    assert cstats.alive() == 0
208

209

210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
def test_non_destructed_holders():
    """ Issue #478: unique ptrs constructed and freed without destruction """
    from pybind11_tests import SpecialHolderObj

    a = SpecialHolderObj(123)
    b = a.child()

    assert a.val == 123
    assert b.val == 124

    cstats = SpecialHolderObj.holder_cstats()
    assert cstats.alive() == 1
    del b
    assert cstats.alive() == 1
    del a
    assert cstats.alive() == 0
226
227
228
229
230
231
232
233
234
235
236


def test_complex_cast(capture):
    """ Issue #484: number conversion generates unhandled exceptions """
    from pybind11_tests.issues import test_complex

    with capture:
        test_complex(1)
        test_complex(2j)

    assert capture == """
237
238
239
        1.0
        (0.0, 2.0)
    """
240
241
242
243
244
245
246
247
248
249
250
251


def test_inheritance_override_def_static():
    from pybind11_tests.issues import MyBase, MyDerived

    b = MyBase.make()
    d1 = MyDerived.make2()
    d2 = MyDerived.make()

    assert isinstance(b, MyBase)
    assert isinstance(d1, MyDerived)
    assert isinstance(d2, MyDerived)