7 from pybind11_tests
import factory_constructors
as m
8 from pybind11_tests.factory_constructors
import tag
9 from pybind11_tests
import ConstructorStats
13 """Tests py::init_factory() wrapper around various ways of returning the object""" 17 n_inst = ConstructorStats.detail_reg_inst()
19 x1 = m.TestFactory1(tag.unique_ptr, 3)
20 assert x1.value ==
"3" 21 y1 = m.TestFactory1(tag.pointer)
22 assert y1.value ==
"(empty)" 23 z1 = m.TestFactory1(
"hi!")
24 assert z1.value ==
"hi!" 26 assert ConstructorStats.detail_reg_inst() == n_inst + 3
28 x2 = m.TestFactory2(tag.move)
29 assert x2.value ==
"(empty2)" 30 y2 = m.TestFactory2(tag.pointer, 7)
31 assert y2.value ==
"7" 32 z2 = m.TestFactory2(tag.unique_ptr,
"hi again")
33 assert z2.value ==
"hi again" 35 assert ConstructorStats.detail_reg_inst() == n_inst + 6
37 x3 = m.TestFactory3(tag.shared_ptr)
38 assert x3.value ==
"(empty3)" 39 y3 = m.TestFactory3(tag.pointer, 42)
40 assert y3.value ==
"42" 41 z3 = m.TestFactory3(
"bye")
42 assert z3.value ==
"bye" 44 for null_ptr_kind
in [tag.null_ptr,
47 with pytest.raises(TypeError)
as excinfo:
48 m.TestFactory3(null_ptr_kind)
49 assert str(excinfo.value) ==
"pybind11::init(): factory function returned nullptr" 51 assert [i.alive()
for i
in cstats] == [3, 3, 3]
52 assert ConstructorStats.detail_reg_inst() == n_inst + 9
55 assert [i.alive()
for i
in cstats] == [2, 2, 1]
56 assert ConstructorStats.detail_reg_inst() == n_inst + 5
57 del x2, x3, y1, z1, z2
58 assert [i.alive()
for i
in cstats] == [0, 0, 0]
59 assert ConstructorStats.detail_reg_inst() == n_inst
61 assert [i.values()
for i
in cstats] == [
66 assert [i.default_constructions
for i
in cstats] == [1, 1, 1]
70 with pytest.raises(TypeError)
as excinfo:
71 m.TestFactory1(
"invalid",
"constructor",
"arguments")
72 assert msg(excinfo.value) ==
""" 73 __init__(): incompatible constructor arguments. The following argument types are supported: 74 1. m.factory_constructors.TestFactory1(arg0: m.factory_constructors.tag.unique_ptr_tag, arg1: int) 75 2. m.factory_constructors.TestFactory1(arg0: str) 76 3. m.factory_constructors.TestFactory1(arg0: m.factory_constructors.tag.pointer_tag) 77 4. m.factory_constructors.TestFactory1(arg0: handle, arg1: int, arg2: handle) 79 Invoked with: 'invalid', 'constructor', 'arguments' 82 assert msg(m.TestFactory1.__init__.__doc__) ==
""" 83 __init__(*args, **kwargs) 86 1. __init__(self: m.factory_constructors.TestFactory1, arg0: m.factory_constructors.tag.unique_ptr_tag, arg1: int) -> None 88 2. __init__(self: m.factory_constructors.TestFactory1, arg0: str) -> None 90 3. __init__(self: m.factory_constructors.TestFactory1, arg0: m.factory_constructors.tag.pointer_tag) -> None 92 4. __init__(self: m.factory_constructors.TestFactory1, arg0: handle, arg1: int, arg2: handle) -> None 97 """Tests py::init_factory() wrapper with various upcasting and downcasting returns""" 101 n_inst = ConstructorStats.detail_reg_inst()
104 a = m.TestFactory3(tag.pointer, tag.TF4, 4)
105 assert a.value ==
"4" 106 b = m.TestFactory3(tag.shared_ptr, tag.TF4, 5)
107 assert b.value ==
"5" 108 c = m.TestFactory3(tag.pointer, tag.TF5, 6)
109 assert c.value ==
"6" 110 d = m.TestFactory3(tag.shared_ptr, tag.TF5, 7)
111 assert d.value ==
"7" 113 assert ConstructorStats.detail_reg_inst() == n_inst + 4
116 e = m.TestFactory4(tag.pointer, tag.TF4, 8)
117 assert e.value ==
"8" 119 assert ConstructorStats.detail_reg_inst() == n_inst + 5
120 assert [i.alive()
for i
in cstats] == [5, 3, 2]
123 assert [i.alive()
for i
in cstats] == [4, 2, 2]
124 assert ConstructorStats.detail_reg_inst() == n_inst + 4
127 assert [i.alive()
for i
in cstats] == [1, 0, 1]
128 assert ConstructorStats.detail_reg_inst() == n_inst + 1
131 assert [i.alive()
for i
in cstats] == [0, 0, 0]
132 assert ConstructorStats.detail_reg_inst() == n_inst
134 assert [i.values()
for i
in cstats] == [
135 [
"4",
"5",
"6",
"7",
"8"],
142 """Tests py::init_factory() wrapper with value conversions and alias types""" 144 cstats = [m.TestFactory6.get_cstats(), m.TestFactory6.get_alias_cstats()]
146 n_inst = ConstructorStats.detail_reg_inst()
148 a = m.TestFactory6(tag.base, 1)
150 assert not a.has_alias()
151 b = m.TestFactory6(tag.alias,
"hi there")
154 c = m.TestFactory6(tag.alias, 3)
157 d = m.TestFactory6(tag.alias, tag.pointer, 4)
160 e = m.TestFactory6(tag.base, tag.pointer, 5)
162 assert not e.has_alias()
163 f = m.TestFactory6(tag.base, tag.alias, tag.pointer, 6)
167 assert ConstructorStats.detail_reg_inst() == n_inst + 6
168 assert [i.alive()
for i
in cstats] == [6, 4]
171 assert [i.alive()
for i
in cstats] == [3, 3]
172 assert ConstructorStats.detail_reg_inst() == n_inst + 3
174 assert [i.alive()
for i
in cstats] == [0, 0]
175 assert ConstructorStats.detail_reg_inst() == n_inst
177 class MyTest(m.TestFactory6):
178 def __init__(self, *args):
179 m.TestFactory6.__init__(self, *args)
182 return -5 + m.TestFactory6.get(self)
185 z = MyTest(tag.base, 123)
186 assert z.get() == 118
190 y = MyTest(tag.alias,
"why hello!")
195 x = MyTest(tag.base, tag.pointer, 47)
199 assert ConstructorStats.detail_reg_inst() == n_inst + 3
200 assert [i.alive()
for i
in cstats] == [3, 3]
202 assert [i.alive()
for i
in cstats] == [0, 0]
203 assert ConstructorStats.detail_reg_inst() == n_inst
205 assert [i.values()
for i
in cstats] == [
206 [
"1",
"8",
"3",
"4",
"5",
"6",
"123",
"10",
"47"],
207 [
"hi there",
"3",
"4",
"6",
"move",
"123",
"why hello!",
"move",
"47"]
212 """Tests init factory functions with dual main/alias factory functions""" 213 from pybind11_tests.factory_constructors
import TestFactory7
215 cstats = [TestFactory7.get_cstats(), TestFactory7.get_alias_cstats()]
217 n_inst = ConstructorStats.detail_reg_inst()
226 assert a2.get() == 102
227 assert not a1.has_alias()
228 assert a2.has_alias()
231 b2 = PythFactory7(tag.pointer, 4)
233 assert b2.get() == 104
234 assert not b1.has_alias()
235 assert b2.has_alias()
238 c2 = PythFactory7(tag.mixed, 6)
240 assert c2.get() == 106
241 assert not c1.has_alias()
242 assert c2.has_alias()
245 d2 = PythFactory7(tag.base, tag.pointer, 8)
247 assert d2.get() == 108
248 assert not d1.has_alias()
249 assert d2.has_alias()
253 e2 = PythFactory7(tag.alias, tag.pointer, 10)
255 assert e2.get() == 200
256 assert e1.has_alias()
257 assert e2.has_alias()
260 f2 = PythFactory7(tag.shared_ptr, tag.base, 12)
261 assert f1.get() == 11
262 assert f2.get() == 112
263 assert not f1.has_alias()
264 assert f2.has_alias()
267 assert g1.get() == 13
268 assert not g1.has_alias()
269 with pytest.raises(TypeError)
as excinfo:
270 PythFactory7(tag.shared_ptr, tag.invalid_base, 14)
271 assert (
str(excinfo.value) ==
272 "pybind11::init(): construction failed: returned holder-wrapped instance is not an " 275 assert [i.alive()
for i
in cstats] == [13, 7]
276 assert ConstructorStats.detail_reg_inst() == n_inst + 13
278 del a1, a2, b1, d1, e1, e2
279 assert [i.alive()
for i
in cstats] == [7, 4]
280 assert ConstructorStats.detail_reg_inst() == n_inst + 7
281 del b2, c1, c2, d2, f1, f2, g1
282 assert [i.alive()
for i
in cstats] == [0, 0]
283 assert ConstructorStats.detail_reg_inst() == n_inst
285 assert [i.values()
for i
in cstats] == [
286 [
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"100",
"11",
"12",
"13",
"14"],
287 [
"2",
"4",
"6",
"8",
"9",
"100",
"12"]
292 """Prior to 2.2, `py::init<...>` relied on the type supporting placement 293 new; this tests a class without placement new support.""" 295 a = m.NoPlacementNew(123)
297 found = re.search(
r'^operator new called, returning (\d+)\n$',
str(capture))
303 assert capture ==
"operator delete called on " + found.group(1)
306 b = m.NoPlacementNew()
308 found = re.search(
r'^operator new called, returning (\d+)\n$',
str(capture))
314 assert capture ==
"operator delete called on " + found.group(1)
318 class MITest(m.TestFactory1, m.TestFactory2):
320 m.TestFactory1.__init__(self, tag.unique_ptr, 33)
321 m.TestFactory2.__init__(self, tag.move)
324 assert m.TestFactory1.value.fget(a) ==
"33" 325 assert m.TestFactory2.value.fget(a) ==
"(empty2)" 329 a = m.NoisyAlloc(*args)
336 return re.sub(
r'\s+#.*',
'', s)
340 """When the constructor is overloaded, previous overloads can require a preallocated value. 341 This test makes sure that such preallocated values only happen when they might be necessary, 342 and that they are deallocated properly.""" 348 assert msg(capture) ==
""" 362 noisy new # allocation required to attempt first overload 363 noisy delete # have to dealloc before considering factory init overload 364 noisy new # pointer factory calling "new", part 1: allocation 365 NoisyAlloc(double 1.5) # ... part two, invoking constructor 367 ~NoisyAlloc() # Destructor 368 noisy delete # operator delete 376 noisy new # pointer factory calling "new", allocation 377 NoisyAlloc(int 2) # constructor 379 ~NoisyAlloc() # Destructor 380 noisy delete # operator delete 388 NoisyAlloc(double 2.5) # construction (local func variable: operator_new not called) 389 noisy new # return-by-value "new" part 1: allocation 390 ~NoisyAlloc() # moved-away local func variable destruction 392 ~NoisyAlloc() # Destructor 393 noisy delete # operator delete 401 noisy new # preallocation needed before invoking placement-new overload 402 noisy placement new # Placement new 403 NoisyAlloc(double 3.5) # construction 405 ~NoisyAlloc() # Destructor 406 noisy delete # operator delete 414 noisy new # preallocation needed before invoking placement-new overload 415 noisy delete # deallocation of preallocated storage 416 noisy new # Factory pointer allocation 417 NoisyAlloc(int 4) # factory pointer construction 419 ~NoisyAlloc() # Destructor 420 noisy delete # operator delete 428 noisy new # preallocation needed before invoking first placement new 429 noisy delete # delete before considering new-style constructor 430 noisy new # preallocation for second placement new 431 noisy placement new # Placement new in the second placement new overload 432 NoisyAlloc(int 5) # construction 434 ~NoisyAlloc() # Destructor 435 noisy delete # operator delete 439 @pytest.mark.skipif(
"env.PY2")
441 """Tests invocation of the pybind-registered base class with an invalid `self` argument. You 442 can only actually do this on Python 3: Python 2 raises an exception itself if you try.""" 443 class NotPybindDerived(
object):
447 class BrokenTF1(m.TestFactory1):
448 def __init__(self, bad):
450 a = m.TestFactory2(tag.pointer, 1)
451 m.TestFactory1.__init__(a, tag.pointer)
453 a = NotPybindDerived()
454 m.TestFactory1.__init__(a, tag.pointer)
457 class BrokenTF6(m.TestFactory6):
458 def __init__(self, bad):
460 a = m.TestFactory2(tag.pointer, 1)
461 m.TestFactory6.__init__(a, tag.base, 1)
463 a = m.TestFactory2(tag.pointer, 1)
464 m.TestFactory6.__init__(a, tag.alias, 1)
466 m.TestFactory6.__init__(NotPybindDerived.__new__(NotPybindDerived), tag.base, 1)
468 m.TestFactory6.__init__(NotPybindDerived.__new__(NotPybindDerived), tag.alias, 1)
471 with pytest.raises(TypeError)
as excinfo:
473 assert str(excinfo.value) ==
"__init__(self, ...) called with invalid `self` argument" 475 for arg
in (1, 2, 3, 4):
476 with pytest.raises(TypeError)
as excinfo:
478 assert str(excinfo.value) ==
"__init__(self, ...) called with invalid `self` argument" void print(const Matrix &A, const string &s, ostream &stream)
def test_reallocation_a(capture, msg)
def create_and_destroy(args)
def test_init_factory_signature(msg)
def test_init_factory_casting()
def test_reallocation_d(capture, msg)
def test_reallocation_g(capture, msg)
static ConstructorStats & get(std::type_index type)
def test_multiple_inheritance()
def test_reallocation_f(capture, msg)
def test_reallocation_e(capture, msg)
def test_init_factory_basic()
def test_no_placement_new(capture)
def test_init_factory_alias()
def test_init_factory_dual()
def test_reallocation_c(capture, msg)
def test_reallocation_b(capture, msg)
Container::iterator get(Container &c, Position position)