test_issues.py 6.56 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


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
49
    pytest.gc_collect()
Dean Moldovan's avatar
Dean Moldovan committed
50
51
52
53
    for i, v in enumerate(el.get()):
        assert i == v.value()


54
def test_no_id(msg):
55
    from pybind11_tests.issues import get_element, expect_float, expect_int
Dean Moldovan's avatar
Dean Moldovan committed
56
57

    with pytest.raises(TypeError) as excinfo:
58
        get_element(None)
Dean Moldovan's avatar
Dean Moldovan committed
59
    assert msg(excinfo.value) == """
60
        get_element(): incompatible function arguments. The following argument types are supported:
61
            1. (arg0: m.issues.ElementA) -> int
62
63

        Invoked with: None
Dean Moldovan's avatar
Dean Moldovan committed
64
65
66
67
68
    """

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

        Invoked with: 5.2
Dean Moldovan's avatar
Dean Moldovan committed
73
74
75
76
    """
    assert expect_float(12) == 12


77
def test_str_issue(msg):
Dean Moldovan's avatar
Dean Moldovan committed
78
79
80
    """Issue #283: __str__ called on uninitialized instance when constructor arguments invalid"""
    from pybind11_tests.issues import StrIssue

81
    assert str(StrIssue(3)) == "StrIssue[3]"
Dean Moldovan's avatar
Dean Moldovan committed
82
83
84
85

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

90
        Invoked with: 'no', 'such', 'constructor'
Dean Moldovan's avatar
Dean Moldovan committed
91
92
93
    """


94
def test_nested():
Dean Moldovan's avatar
Dean Moldovan committed
95
    """ #328: first member in a class can't be used in operators"""
96
    from pybind11_tests.issues import NestA, NestB, NestC, get_NestA, get_NestB, get_NestC
Dean Moldovan's avatar
Dean Moldovan committed
97
98
99
100
101
102

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

    a += 10
103
    assert get_NestA(a) == 13
Dean Moldovan's avatar
Dean Moldovan committed
104
    b.a += 100
105
    assert get_NestA(b.a) == 103
Dean Moldovan's avatar
Dean Moldovan committed
106
    c.b.a += 1000
107
    assert get_NestA(c.b.a) == 1003
Dean Moldovan's avatar
Dean Moldovan committed
108
    b -= 1
109
    assert get_NestB(b) == 3
Dean Moldovan's avatar
Dean Moldovan committed
110
    c.b -= 3
111
    assert get_NestB(c.b) == 1
Dean Moldovan's avatar
Dean Moldovan committed
112
    c *= 7
113
    assert get_NestC(c) == 35
Dean Moldovan's avatar
Dean Moldovan committed
114
115
116
117
118
119
120
121
122
123

    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
124
    pytest.gc_collect()
Dean Moldovan's avatar
Dean Moldovan committed
125
    del a  # Should't delete while abase is still alive
Wenzel Jakob's avatar
Wenzel Jakob committed
126
    pytest.gc_collect()
Dean Moldovan's avatar
Dean Moldovan committed
127
128
129

    assert abase.value == 42
    del abase, b
Wenzel Jakob's avatar
Wenzel Jakob committed
130
    pytest.gc_collect()
131
132
133
134
135
136
137
138


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
139

140

141
142
def test_override_ref():
    from pybind11_tests.issues import OverrideTest
143
    o = OverrideTest("asdf")
144

145
    # Not allowed (see associated .cpp comment)
146
147
    # i = o.str_ref()
    # assert o.str_ref() == "asdf"
148
    assert o.str_value() == "asdf"
149

150
    assert o.A_value().value == "hi"
151
    a = o.A_ref()
152
153
154
    assert a.value == "hi"
    a.value = "bye"
    assert a.value == "bye"
155

156

157
158
159
def test_operators_notimplemented(capture):
    from pybind11_tests.issues import OpTest1, OpTest2
    with capture:
160
161
162
163
164
165
166
167
168
169
170
        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
    """
171

172

173
174
175
176
177
178
179
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]
180
    assert not isinstance(make_iterator_1(), type(make_iterator_2()))
181

182

183
184
185
186
def test_dupe_assignment():
    """ Issue 461: overwriting a class with a function """
    from pybind11_tests.issues import dupe_exception_failures
    assert dupe_exception_failures() == []
187
188
189
190
191
192
193
194
195
196
197
198
199


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
200

201

202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
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
218
219
220
221
222
223
224
225
226
227
228


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 == """
229
230
231
        1.0
        (0.0, 2.0)
    """
232
233
234
235
236
237
238
239
240
241
242
243


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)