Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 1 | import pytest |
| 2 | import gc |
Wenzel Jakob | bd560ac | 2016-11-03 11:53:35 +0100 | [diff] [blame] | 3 | from pybind11_tests import ConstructorStats |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 4 | |
| 5 | |
Dean Moldovan | 665e880 | 2016-08-12 22:28:31 +0200 | [diff] [blame] | 6 | def test_regressions(): |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 7 | from pybind11_tests.issues import print_cchar, print_char |
| 8 | |
Dean Moldovan | 665e880 | 2016-08-12 22:28:31 +0200 | [diff] [blame] | 9 | # #137: const char* isn't handled properly |
| 10 | assert print_cchar("const char *") == "const char *" |
| 11 | # #150: char bindings broken |
| 12 | assert print_char("c") == "c" |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 13 | |
| 14 | |
Dean Moldovan | 665e880 | 2016-08-12 22:28:31 +0200 | [diff] [blame] | 15 | def test_dispatch_issue(msg): |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 16 | """#159: virtual function dispatch has problems with similar-named functions""" |
| 17 | from pybind11_tests.issues import DispatchIssue, dispatch_issue_go |
| 18 | |
| 19 | class PyClass1(DispatchIssue): |
| 20 | def dispatch(self): |
Dean Moldovan | 665e880 | 2016-08-12 22:28:31 +0200 | [diff] [blame] | 21 | return "Yay.." |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 22 | |
| 23 | class PyClass2(DispatchIssue): |
| 24 | def dispatch(self): |
| 25 | with pytest.raises(RuntimeError) as excinfo: |
| 26 | super(PyClass2, self).dispatch() |
| 27 | assert msg(excinfo.value) == 'Tried to call pure virtual function "Base::dispatch"' |
| 28 | |
| 29 | p = PyClass1() |
Dean Moldovan | 665e880 | 2016-08-12 22:28:31 +0200 | [diff] [blame] | 30 | return dispatch_issue_go(p) |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 31 | |
| 32 | b = PyClass2() |
Dean Moldovan | 665e880 | 2016-08-12 22:28:31 +0200 | [diff] [blame] | 33 | assert dispatch_issue_go(b) == "Yay.." |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 34 | |
| 35 | |
| 36 | def test_reference_wrapper(): |
| 37 | """#171: Can't return reference wrappers (or STL data structures containing them)""" |
| 38 | from pybind11_tests.issues import Placeholder, return_vec_of_reference_wrapper |
| 39 | |
| 40 | assert str(return_vec_of_reference_wrapper(Placeholder(4))) == \ |
| 41 | "[Placeholder[1], Placeholder[2], Placeholder[3], Placeholder[4]]" |
| 42 | |
| 43 | |
| 44 | def test_iterator_passthrough(): |
| 45 | """#181: iterator passthrough did not compile""" |
| 46 | from pybind11_tests.issues import iterator_passthrough |
| 47 | |
| 48 | assert list(iterator_passthrough(iter([3, 5, 7, 9, 11, 13, 15]))) == [3, 5, 7, 9, 11, 13, 15] |
| 49 | |
| 50 | |
| 51 | def test_shared_ptr_gc(): |
| 52 | """// #187: issue involving std::shared_ptr<> return value policy & garbage collection""" |
| 53 | from pybind11_tests.issues import ElementList, ElementA |
| 54 | |
| 55 | el = ElementList() |
| 56 | for i in range(10): |
| 57 | el.add(ElementA(i)) |
| 58 | gc.collect() |
| 59 | for i, v in enumerate(el.get()): |
| 60 | assert i == v.value() |
| 61 | |
| 62 | |
Wenzel Jakob | fe40dfe | 2016-11-07 15:59:01 +0100 | [diff] [blame] | 63 | def test_no_id(msg): |
Dean Moldovan | 99dbdc1 | 2016-08-19 13:45:36 +0200 | [diff] [blame] | 64 | from pybind11_tests.issues import get_element, expect_float, expect_int |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 65 | |
| 66 | with pytest.raises(TypeError) as excinfo: |
Dean Moldovan | 99dbdc1 | 2016-08-19 13:45:36 +0200 | [diff] [blame] | 67 | get_element(None) |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 68 | assert msg(excinfo.value) == """ |
Wenzel Jakob | e99ebae | 2016-09-12 11:44:37 +0900 | [diff] [blame] | 69 | get_element(): incompatible function arguments. The following argument types are supported: |
Dean Moldovan | 99dbdc1 | 2016-08-19 13:45:36 +0200 | [diff] [blame] | 70 | 1. (arg0: m.issues.ElementA) -> int |
Wenzel Jakob | e99ebae | 2016-09-12 11:44:37 +0900 | [diff] [blame] | 71 | |
| 72 | Invoked with: None |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 73 | """ |
| 74 | |
| 75 | with pytest.raises(TypeError) as excinfo: |
| 76 | expect_int(5.2) |
| 77 | assert msg(excinfo.value) == """ |
Wenzel Jakob | e99ebae | 2016-09-12 11:44:37 +0900 | [diff] [blame] | 78 | expect_int(): incompatible function arguments. The following argument types are supported: |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 79 | 1. (arg0: int) -> int |
Wenzel Jakob | e99ebae | 2016-09-12 11:44:37 +0900 | [diff] [blame] | 80 | |
| 81 | Invoked with: 5.2 |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 82 | """ |
| 83 | assert expect_float(12) == 12 |
| 84 | |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 85 | |
Dean Moldovan | 99dbdc1 | 2016-08-19 13:45:36 +0200 | [diff] [blame] | 86 | def test_str_issue(msg): |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 87 | """Issue #283: __str__ called on uninitialized instance when constructor arguments invalid""" |
| 88 | from pybind11_tests.issues import StrIssue |
| 89 | |
Dean Moldovan | 99dbdc1 | 2016-08-19 13:45:36 +0200 | [diff] [blame] | 90 | assert str(StrIssue(3)) == "StrIssue[3]" |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 91 | |
| 92 | with pytest.raises(TypeError) as excinfo: |
| 93 | str(StrIssue("no", "such", "constructor")) |
| 94 | assert msg(excinfo.value) == """ |
Wenzel Jakob | e99ebae | 2016-09-12 11:44:37 +0900 | [diff] [blame] | 95 | __init__(): incompatible constructor arguments. The following argument types are supported: |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 96 | 1. m.issues.StrIssue(arg0: int) |
| 97 | 2. m.issues.StrIssue() |
Wenzel Jakob | e99ebae | 2016-09-12 11:44:37 +0900 | [diff] [blame] | 98 | |
Jason Rhinelander | 7146d62 | 2016-11-22 05:28:40 -0500 | [diff] [blame] | 99 | Invoked with: 'no', 'such', 'constructor' |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 100 | """ |
| 101 | |
| 102 | |
Dean Moldovan | 665e880 | 2016-08-12 22:28:31 +0200 | [diff] [blame] | 103 | def test_nested(): |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 104 | """ #328: first member in a class can't be used in operators""" |
Dean Moldovan | 665e880 | 2016-08-12 22:28:31 +0200 | [diff] [blame] | 105 | from pybind11_tests.issues import NestA, NestB, NestC, get_NestA, get_NestB, get_NestC |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 106 | |
| 107 | a = NestA() |
| 108 | b = NestB() |
| 109 | c = NestC() |
| 110 | |
| 111 | a += 10 |
Dean Moldovan | 665e880 | 2016-08-12 22:28:31 +0200 | [diff] [blame] | 112 | assert get_NestA(a) == 13 |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 113 | b.a += 100 |
Dean Moldovan | 665e880 | 2016-08-12 22:28:31 +0200 | [diff] [blame] | 114 | assert get_NestA(b.a) == 103 |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 115 | c.b.a += 1000 |
Dean Moldovan | 665e880 | 2016-08-12 22:28:31 +0200 | [diff] [blame] | 116 | assert get_NestA(c.b.a) == 1003 |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 117 | b -= 1 |
Dean Moldovan | 665e880 | 2016-08-12 22:28:31 +0200 | [diff] [blame] | 118 | assert get_NestB(b) == 3 |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 119 | c.b -= 3 |
Dean Moldovan | 665e880 | 2016-08-12 22:28:31 +0200 | [diff] [blame] | 120 | assert get_NestB(c.b) == 1 |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 121 | c *= 7 |
Dean Moldovan | 665e880 | 2016-08-12 22:28:31 +0200 | [diff] [blame] | 122 | assert get_NestC(c) == 35 |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 123 | |
| 124 | abase = a.as_base() |
| 125 | assert abase.value == -2 |
| 126 | a.as_base().value += 44 |
| 127 | assert abase.value == 42 |
| 128 | assert c.b.a.as_base().value == -2 |
| 129 | c.b.a.as_base().value += 44 |
| 130 | assert c.b.a.as_base().value == 42 |
| 131 | |
| 132 | del c |
| 133 | gc.collect() |
| 134 | del a # Should't delete while abase is still alive |
| 135 | gc.collect() |
| 136 | |
| 137 | assert abase.value == 42 |
| 138 | del abase, b |
| 139 | gc.collect() |
Wenzel Jakob | c84b37b | 2016-09-07 00:47:17 +0900 | [diff] [blame] | 140 | |
| 141 | |
| 142 | def test_move_fallback(): |
| 143 | from pybind11_tests.issues import get_moveissue1, get_moveissue2 |
| 144 | m2 = get_moveissue2(2) |
| 145 | assert m2.value == 2 |
| 146 | m1 = get_moveissue1(1) |
| 147 | assert m1.value == 1 |
Jason Rhinelander | 56f7177 | 2016-09-07 13:32:49 -0400 | [diff] [blame] | 148 | |
Wenzel Jakob | fe40dfe | 2016-11-07 15:59:01 +0100 | [diff] [blame] | 149 | |
Jason Rhinelander | 56f7177 | 2016-09-07 13:32:49 -0400 | [diff] [blame] | 150 | def test_override_ref(): |
| 151 | from pybind11_tests.issues import OverrideTest |
Jason Rhinelander | 9c6859e | 2016-09-08 11:03:08 -0400 | [diff] [blame] | 152 | o = OverrideTest("asdf") |
Jason Rhinelander | 56f7177 | 2016-09-07 13:32:49 -0400 | [diff] [blame] | 153 | |
Jason Rhinelander | c03db9b | 2016-09-07 13:38:32 -0400 | [diff] [blame] | 154 | # Not allowed (see associated .cpp comment) |
Dean Moldovan | bad1740 | 2016-11-20 21:21:54 +0100 | [diff] [blame] | 155 | # i = o.str_ref() |
| 156 | # assert o.str_ref() == "asdf" |
Jason Rhinelander | 9c6859e | 2016-09-08 11:03:08 -0400 | [diff] [blame] | 157 | assert o.str_value() == "asdf" |
Jason Rhinelander | 56f7177 | 2016-09-07 13:32:49 -0400 | [diff] [blame] | 158 | |
Jason Rhinelander | 9c6859e | 2016-09-08 11:03:08 -0400 | [diff] [blame] | 159 | assert o.A_value().value == "hi" |
Jason Rhinelander | 56f7177 | 2016-09-07 13:32:49 -0400 | [diff] [blame] | 160 | a = o.A_ref() |
Jason Rhinelander | 9c6859e | 2016-09-08 11:03:08 -0400 | [diff] [blame] | 161 | assert a.value == "hi" |
| 162 | a.value = "bye" |
| 163 | assert a.value == "bye" |
Wenzel Jakob | 382484a | 2016-09-10 15:28:37 +0900 | [diff] [blame] | 164 | |
Wenzel Jakob | fe40dfe | 2016-11-07 15:59:01 +0100 | [diff] [blame] | 165 | |
Wenzel Jakob | 382484a | 2016-09-10 15:28:37 +0900 | [diff] [blame] | 166 | def test_operators_notimplemented(capture): |
| 167 | from pybind11_tests.issues import OpTest1, OpTest2 |
| 168 | with capture: |
Dean Moldovan | bad1740 | 2016-11-20 21:21:54 +0100 | [diff] [blame] | 169 | c1, c2 = OpTest1(), OpTest2() |
| 170 | c1 + c1 |
| 171 | c2 + c2 |
| 172 | c2 + c1 |
| 173 | c1 + c2 |
| 174 | assert capture == """ |
| 175 | Add OpTest1 with OpTest1 |
| 176 | Add OpTest2 with OpTest2 |
| 177 | Add OpTest2 with OpTest1 |
| 178 | Add OpTest2 with OpTest1 |
| 179 | """ |
Wenzel Jakob | b212f6c | 2016-09-10 16:00:50 +0900 | [diff] [blame] | 180 | |
Wenzel Jakob | fe40dfe | 2016-11-07 15:59:01 +0100 | [diff] [blame] | 181 | |
Wenzel Jakob | b212f6c | 2016-09-10 16:00:50 +0900 | [diff] [blame] | 182 | def test_iterator_rvpolicy(): |
| 183 | """ Issue 388: Can't make iterators via make_iterator() with different r/v policies """ |
| 184 | from pybind11_tests.issues import make_iterator_1 |
| 185 | from pybind11_tests.issues import make_iterator_2 |
| 186 | |
| 187 | assert list(make_iterator_1()) == [1, 2, 3] |
| 188 | assert list(make_iterator_2()) == [1, 2, 3] |
Dean Moldovan | bad1740 | 2016-11-20 21:21:54 +0100 | [diff] [blame] | 189 | assert not isinstance(make_iterator_1(), type(make_iterator_2())) |
Jason Rhinelander | 6873c20 | 2016-10-24 21:58:22 -0400 | [diff] [blame] | 190 | |
Wenzel Jakob | fe40dfe | 2016-11-07 15:59:01 +0100 | [diff] [blame] | 191 | |
Jason Rhinelander | 6873c20 | 2016-10-24 21:58:22 -0400 | [diff] [blame] | 192 | def test_dupe_assignment(): |
| 193 | """ Issue 461: overwriting a class with a function """ |
| 194 | from pybind11_tests.issues import dupe_exception_failures |
| 195 | assert dupe_exception_failures() == [] |
Wenzel Jakob | bd560ac | 2016-11-03 11:53:35 +0100 | [diff] [blame] | 196 | |
| 197 | |
| 198 | def test_enable_shared_from_this_with_reference_rvp(): |
| 199 | """ Issue #471: shared pointer instance not dellocated """ |
| 200 | from pybind11_tests import SharedParent, SharedChild |
| 201 | |
| 202 | parent = SharedParent() |
| 203 | child = parent.get_child() |
| 204 | |
| 205 | cstats = ConstructorStats.get(SharedChild) |
| 206 | assert cstats.alive() == 1 |
| 207 | del child, parent |
| 208 | assert cstats.alive() == 0 |
Jason Rhinelander | c07ec31 | 2016-11-06 13:12:48 -0500 | [diff] [blame] | 209 | |
Wenzel Jakob | fe40dfe | 2016-11-07 15:59:01 +0100 | [diff] [blame] | 210 | |
Jason Rhinelander | c07ec31 | 2016-11-06 13:12:48 -0500 | [diff] [blame] | 211 | def test_non_destructed_holders(): |
| 212 | """ Issue #478: unique ptrs constructed and freed without destruction """ |
| 213 | from pybind11_tests import SpecialHolderObj |
| 214 | |
| 215 | a = SpecialHolderObj(123) |
| 216 | b = a.child() |
| 217 | |
| 218 | assert a.val == 123 |
| 219 | assert b.val == 124 |
| 220 | |
| 221 | cstats = SpecialHolderObj.holder_cstats() |
| 222 | assert cstats.alive() == 1 |
| 223 | del b |
| 224 | assert cstats.alive() == 1 |
| 225 | del a |
| 226 | assert cstats.alive() == 0 |
Wenzel Jakob | fe40dfe | 2016-11-07 15:59:01 +0100 | [diff] [blame] | 227 | |
| 228 | |
| 229 | def test_complex_cast(capture): |
| 230 | """ Issue #484: number conversion generates unhandled exceptions """ |
| 231 | from pybind11_tests.issues import test_complex |
| 232 | |
| 233 | with capture: |
| 234 | test_complex(1) |
| 235 | test_complex(2j) |
| 236 | |
| 237 | assert capture == """ |
Dean Moldovan | bad1740 | 2016-11-20 21:21:54 +0100 | [diff] [blame] | 238 | 1.0 |
| 239 | (0.0, 2.0) |
| 240 | """ |
Wenzel Jakob | 7c2461e | 2016-11-20 05:26:02 +0100 | [diff] [blame] | 241 | |
| 242 | |
| 243 | def test_inheritance_override_def_static(): |
| 244 | from pybind11_tests.issues import MyBase, MyDerived |
| 245 | |
| 246 | b = MyBase.make() |
| 247 | d1 = MyDerived.make2() |
| 248 | d2 = MyDerived.make() |
| 249 | |
| 250 | assert isinstance(b, MyBase) |
| 251 | assert isinstance(d1, MyDerived) |
| 252 | assert isinstance(d2, MyDerived) |