Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame^] | 1 | import pytest |
| 2 | import gc |
| 3 | |
| 4 | |
| 5 | def test_regressions(capture): |
| 6 | from pybind11_tests.issues import print_cchar, print_char |
| 7 | |
| 8 | with capture: |
| 9 | print_cchar("const char *") # #137: const char* isn't handled properly |
| 10 | assert capture == "const char *" |
| 11 | with capture: |
| 12 | print_char("c") # #150: char bindings broken |
| 13 | assert capture == "c" |
| 14 | |
| 15 | |
| 16 | def test_dispatch_issue(capture, msg): |
| 17 | """#159: virtual function dispatch has problems with similar-named functions""" |
| 18 | from pybind11_tests.issues import DispatchIssue, dispatch_issue_go |
| 19 | |
| 20 | class PyClass1(DispatchIssue): |
| 21 | def dispatch(self): |
| 22 | print("Yay..") |
| 23 | |
| 24 | class PyClass2(DispatchIssue): |
| 25 | def dispatch(self): |
| 26 | with pytest.raises(RuntimeError) as excinfo: |
| 27 | super(PyClass2, self).dispatch() |
| 28 | assert msg(excinfo.value) == 'Tried to call pure virtual function "Base::dispatch"' |
| 29 | |
| 30 | p = PyClass1() |
| 31 | dispatch_issue_go(p) |
| 32 | |
| 33 | b = PyClass2() |
| 34 | with capture: |
| 35 | dispatch_issue_go(b) |
| 36 | assert capture == "Yay.." |
| 37 | |
| 38 | |
| 39 | def test_reference_wrapper(): |
| 40 | """#171: Can't return reference wrappers (or STL data structures containing them)""" |
| 41 | from pybind11_tests.issues import Placeholder, return_vec_of_reference_wrapper |
| 42 | |
| 43 | assert str(return_vec_of_reference_wrapper(Placeholder(4))) == \ |
| 44 | "[Placeholder[1], Placeholder[2], Placeholder[3], Placeholder[4]]" |
| 45 | |
| 46 | |
| 47 | def test_iterator_passthrough(): |
| 48 | """#181: iterator passthrough did not compile""" |
| 49 | from pybind11_tests.issues import iterator_passthrough |
| 50 | |
| 51 | assert list(iterator_passthrough(iter([3, 5, 7, 9, 11, 13, 15]))) == [3, 5, 7, 9, 11, 13, 15] |
| 52 | |
| 53 | |
| 54 | def test_shared_ptr_gc(): |
| 55 | """// #187: issue involving std::shared_ptr<> return value policy & garbage collection""" |
| 56 | from pybind11_tests.issues import ElementList, ElementA |
| 57 | |
| 58 | el = ElementList() |
| 59 | for i in range(10): |
| 60 | el.add(ElementA(i)) |
| 61 | gc.collect() |
| 62 | for i, v in enumerate(el.get()): |
| 63 | assert i == v.value() |
| 64 | |
| 65 | |
| 66 | def test_no_id(capture, msg): |
| 67 | from pybind11_tests.issues import print_element, expect_float, expect_int |
| 68 | |
| 69 | with pytest.raises(TypeError) as excinfo: |
| 70 | print_element(None) |
| 71 | assert msg(excinfo.value) == """ |
| 72 | Incompatible function arguments. The following argument types are supported: |
| 73 | 1. (arg0: m.issues.ElementA) -> None |
| 74 | Invoked with: None |
| 75 | """ |
| 76 | |
| 77 | with pytest.raises(TypeError) as excinfo: |
| 78 | expect_int(5.2) |
| 79 | assert msg(excinfo.value) == """ |
| 80 | Incompatible function arguments. The following argument types are supported: |
| 81 | 1. (arg0: int) -> int |
| 82 | Invoked with: 5.2 |
| 83 | """ |
| 84 | assert expect_float(12) == 12 |
| 85 | |
| 86 | from pybind11_tests.issues import A, call_f |
| 87 | |
| 88 | class B(A): |
| 89 | def __init__(self): |
| 90 | super(B, self).__init__() |
| 91 | |
| 92 | def f(self): |
| 93 | print("In python f()") |
| 94 | |
| 95 | # C++ version |
| 96 | with capture: |
| 97 | a = A() |
| 98 | call_f(a) |
| 99 | assert capture == "A.f()" |
| 100 | |
| 101 | # Python version |
| 102 | with capture: |
| 103 | b = B() |
| 104 | call_f(b) |
| 105 | assert capture == """ |
| 106 | PyA.PyA() |
| 107 | PyA.f() |
| 108 | In python f() |
| 109 | """ |
| 110 | |
| 111 | |
| 112 | def test_str_issue(capture, msg): |
| 113 | """Issue #283: __str__ called on uninitialized instance when constructor arguments invalid""" |
| 114 | from pybind11_tests.issues import StrIssue |
| 115 | |
| 116 | with capture: |
| 117 | assert str(StrIssue(3)) == "StrIssue[3]" |
| 118 | assert capture == "StrIssue.__str__ called" |
| 119 | |
| 120 | with pytest.raises(TypeError) as excinfo: |
| 121 | str(StrIssue("no", "such", "constructor")) |
| 122 | assert msg(excinfo.value) == """ |
| 123 | Incompatible constructor arguments. The following argument types are supported: |
| 124 | 1. m.issues.StrIssue(arg0: int) |
| 125 | 2. m.issues.StrIssue() |
| 126 | Invoked with: no, such, constructor |
| 127 | """ |
| 128 | |
| 129 | |
| 130 | def test_nested(capture): |
| 131 | """ #328: first member in a class can't be used in operators""" |
| 132 | from pybind11_tests.issues import NestA, NestB, NestC, print_NestA, print_NestB, print_NestC |
| 133 | |
| 134 | a = NestA() |
| 135 | b = NestB() |
| 136 | c = NestC() |
| 137 | |
| 138 | a += 10 |
| 139 | b.a += 100 |
| 140 | c.b.a += 1000 |
| 141 | b -= 1 |
| 142 | c.b -= 3 |
| 143 | c *= 7 |
| 144 | |
| 145 | with capture: |
| 146 | print_NestA(a) |
| 147 | print_NestA(b.a) |
| 148 | print_NestA(c.b.a) |
| 149 | print_NestB(b) |
| 150 | print_NestB(c.b) |
| 151 | print_NestC(c) |
| 152 | assert capture == """ |
| 153 | 13 |
| 154 | 103 |
| 155 | 1003 |
| 156 | 3 |
| 157 | 1 |
| 158 | 35 |
| 159 | """ |
| 160 | |
| 161 | abase = a.as_base() |
| 162 | assert abase.value == -2 |
| 163 | a.as_base().value += 44 |
| 164 | assert abase.value == 42 |
| 165 | assert c.b.a.as_base().value == -2 |
| 166 | c.b.a.as_base().value += 44 |
| 167 | assert c.b.a.as_base().value == 42 |
| 168 | |
| 169 | del c |
| 170 | gc.collect() |
| 171 | del a # Should't delete while abase is still alive |
| 172 | gc.collect() |
| 173 | |
| 174 | assert abase.value == 42 |
| 175 | del abase, b |
| 176 | gc.collect() |