1 /*
2     tests/test_class.cpp -- test py::class_ definitions and basic functionality
3 
4     Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
5 
6     All rights reserved. Use of this source code is governed by a
7     BSD-style license that can be found in the LICENSE file.
8 */
9 
10 #if defined(__INTEL_COMPILER) && __cplusplus >= 201703L
11 // Intel compiler requires a separate header file to support aligned new operators
12 // and does not set the __cpp_aligned_new feature macro.
13 // This header needs to be included before pybind11.
14 #include <aligned_new>
15 #endif
16 
17 #include "pybind11_tests.h"
18 #include "constructor_stats.h"
19 #include "local_bindings.h"
20 #include <pybind11/stl.h>
21 
22 #include <utility>
23 
24 #if defined(_MSC_VER)
25 #  pragma warning(disable: 4324) // warning C4324: structure was padded due to alignment specifier
26 #endif
27 
28 // test_brace_initialization
29 struct NoBraceInitialization {
NoBraceInitializationNoBraceInitialization30     explicit NoBraceInitialization(std::vector<int> v) : vec{std::move(v)} {}
31     template <typename T>
NoBraceInitializationNoBraceInitialization32     NoBraceInitialization(std::initializer_list<T> l) : vec(l) {}
33 
34     std::vector<int> vec;
35 };
36 
TEST_SUBMODULE(class_,m)37 TEST_SUBMODULE(class_, m) {
38     // test_instance
39     struct NoConstructor {
40         NoConstructor() = default;
41         NoConstructor(const NoConstructor &) = default;
42         NoConstructor(NoConstructor &&) = default;
43         static NoConstructor *new_instance() {
44             auto *ptr = new NoConstructor();
45             print_created(ptr, "via new_instance");
46             return ptr;
47         }
48         ~NoConstructor() { print_destroyed(this); }
49     };
50     struct NoConstructorNew {
51         NoConstructorNew() = default;
52         NoConstructorNew(const NoConstructorNew &) = default;
53         NoConstructorNew(NoConstructorNew &&) = default;
54         static NoConstructorNew *new_instance() {
55             auto *ptr = new NoConstructorNew();
56             print_created(ptr, "via new_instance");
57             return ptr;
58         }
59         ~NoConstructorNew() { print_destroyed(this); }
60     };
61 
62     py::class_<NoConstructor>(m, "NoConstructor")
63         .def_static("new_instance", &NoConstructor::new_instance, "Return an instance");
64 
65     py::class_<NoConstructorNew>(m, "NoConstructorNew")
66         .def(py::init([](const NoConstructorNew &self) { return self; })) // Need a NOOP __init__
67         .def_static("__new__",
68                     [](const py::object &) { return NoConstructorNew::new_instance(); });
69 
70     // test_inheritance
71     class Pet {
72     public:
73         Pet(const std::string &name, const std::string &species)
74             : m_name(name), m_species(species) {}
75         std::string name() const { return m_name; }
76         std::string species() const { return m_species; }
77     private:
78         std::string m_name;
79         std::string m_species;
80     };
81 
82     class Dog : public Pet {
83     public:
84         explicit Dog(const std::string &name) : Pet(name, "dog") {}
85         std::string bark() const { return "Woof!"; }
86     };
87 
88     class Rabbit : public Pet {
89     public:
90         explicit Rabbit(const std::string &name) : Pet(name, "parrot") {}
91     };
92 
93     class Hamster : public Pet {
94     public:
95         explicit Hamster(const std::string &name) : Pet(name, "rodent") {}
96     };
97 
98     class Chimera : public Pet {
99         Chimera() : Pet("Kimmy", "chimera") {}
100     };
101 
102     py::class_<Pet> pet_class(m, "Pet");
103     pet_class
104         .def(py::init<std::string, std::string>())
105         .def("name", &Pet::name)
106         .def("species", &Pet::species);
107 
108     /* One way of declaring a subclass relationship: reference parent's class_ object */
109     py::class_<Dog>(m, "Dog", pet_class)
110         .def(py::init<std::string>());
111 
112     /* Another way of declaring a subclass relationship: reference parent's C++ type */
113     py::class_<Rabbit, Pet>(m, "Rabbit")
114         .def(py::init<std::string>());
115 
116     /* And another: list parent in class template arguments */
117     py::class_<Hamster, Pet>(m, "Hamster")
118         .def(py::init<std::string>());
119 
120     /* Constructors are not inherited by default */
121     py::class_<Chimera, Pet>(m, "Chimera");
122 
123     m.def("pet_name_species", [](const Pet &pet) { return pet.name() + " is a " + pet.species(); });
124     m.def("dog_bark", [](const Dog &dog) { return dog.bark(); });
125 
126     // test_automatic_upcasting
127     struct BaseClass {
128         BaseClass() = default;
129         BaseClass(const BaseClass &) = default;
130         BaseClass(BaseClass &&) = default;
131         virtual ~BaseClass() = default;
132     };
133     struct DerivedClass1 : BaseClass { };
134     struct DerivedClass2 : BaseClass { };
135 
136     py::class_<BaseClass>(m, "BaseClass").def(py::init<>());
137     py::class_<DerivedClass1>(m, "DerivedClass1").def(py::init<>());
138     py::class_<DerivedClass2>(m, "DerivedClass2").def(py::init<>());
139 
140     m.def("return_class_1", []() -> BaseClass* { return new DerivedClass1(); });
141     m.def("return_class_2", []() -> BaseClass* { return new DerivedClass2(); });
142     m.def("return_class_n", [](int n) -> BaseClass* {
143         if (n == 1) return new DerivedClass1();
144         if (n == 2) return new DerivedClass2();
145         return new BaseClass();
146     });
147     m.def("return_none", []() -> BaseClass* { return nullptr; });
148 
149     // test_isinstance
150     m.def("check_instances", [](const py::list &l) {
151         return py::make_tuple(
152             py::isinstance<py::tuple>(l[0]),
153             py::isinstance<py::dict>(l[1]),
154             py::isinstance<Pet>(l[2]),
155             py::isinstance<Pet>(l[3]),
156             py::isinstance<Dog>(l[4]),
157             py::isinstance<Rabbit>(l[5]),
158             py::isinstance<UnregisteredType>(l[6])
159         );
160     });
161 
162     struct Invalid {};
163 
164     // test_type
165     m.def("check_type", [](int category) {
166         // Currently not supported (via a fail at compile time)
167         // See https://github.com/pybind/pybind11/issues/2486
168         // if (category == 2)
169         //     return py::type::of<int>();
170         if (category == 1)
171             return py::type::of<DerivedClass1>();
172         return py::type::of<Invalid>();
173     });
174 
175     m.def("get_type_of", [](py::object ob) { return py::type::of(std::move(ob)); });
176 
177     m.def("get_type_classic", [](py::handle h) {
178         return h.get_type();
179     });
180 
181     m.def("as_type", [](const py::object &ob) { return py::type(ob); });
182 
183     // test_mismatched_holder
184     struct MismatchBase1 { };
185     struct MismatchDerived1 : MismatchBase1 { };
186 
187     struct MismatchBase2 { };
188     struct MismatchDerived2 : MismatchBase2 { };
189 
190     m.def("mismatched_holder_1", []() {
191         auto mod = py::module_::import("__main__");
192         py::class_<MismatchBase1, std::shared_ptr<MismatchBase1>>(mod, "MismatchBase1");
193         py::class_<MismatchDerived1, MismatchBase1>(mod, "MismatchDerived1");
194     });
195     m.def("mismatched_holder_2", []() {
196         auto mod = py::module_::import("__main__");
197         py::class_<MismatchBase2>(mod, "MismatchBase2");
198         py::class_<MismatchDerived2, std::shared_ptr<MismatchDerived2>,
199                    MismatchBase2>(mod, "MismatchDerived2");
200     });
201 
202     // test_override_static
203     // #511: problem with inheritance + overwritten def_static
204     struct MyBase {
205         static std::unique_ptr<MyBase> make() {
206             return std::unique_ptr<MyBase>(new MyBase());
207         }
208     };
209 
210     struct MyDerived : MyBase {
211         static std::unique_ptr<MyDerived> make() {
212             return std::unique_ptr<MyDerived>(new MyDerived());
213         }
214     };
215 
216     py::class_<MyBase>(m, "MyBase")
217         .def_static("make", &MyBase::make);
218 
219     py::class_<MyDerived, MyBase>(m, "MyDerived")
220         .def_static("make", &MyDerived::make)
221         .def_static("make2", &MyDerived::make);
222 
223     // test_implicit_conversion_life_support
224     struct ConvertibleFromUserType {
225         int i;
226 
227         explicit ConvertibleFromUserType(UserType u) : i(u.value()) {}
228     };
229 
230     py::class_<ConvertibleFromUserType>(m, "AcceptsUserType")
231         .def(py::init<UserType>());
232     py::implicitly_convertible<UserType, ConvertibleFromUserType>();
233 
234     m.def("implicitly_convert_argument", [](const ConvertibleFromUserType &r) { return r.i; });
235     m.def("implicitly_convert_variable", [](const py::object &o) {
236         // `o` is `UserType` and `r` is a reference to a temporary created by implicit
237         // conversion. This is valid when called inside a bound function because the temp
238         // object is attached to the same life support system as the arguments.
239         const auto &r = o.cast<const ConvertibleFromUserType &>();
240         return r.i;
241     });
242     m.add_object("implicitly_convert_variable_fail", [&] {
243         auto f = [](PyObject *, PyObject *args) -> PyObject * {
244             auto o = py::reinterpret_borrow<py::tuple>(args)[0];
245             try { // It should fail here because there is no life support.
246                 o.cast<const ConvertibleFromUserType &>();
247             } catch (const py::cast_error &e) {
248                 return py::str(e.what()).release().ptr();
249             }
250             return py::str().release().ptr();
251         };
252 
253         auto def = new PyMethodDef{"f", f, METH_VARARGS, nullptr};
254         py::capsule def_capsule(def, [](void *ptr) { delete reinterpret_cast<PyMethodDef *>(ptr); });
255         return py::reinterpret_steal<py::object>(PyCFunction_NewEx(def, def_capsule.ptr(), m.ptr()));
256     }());
257 
258     // test_operator_new_delete
259     struct HasOpNewDel {
260         std::uint64_t i;
261         static void *operator new(size_t s) { py::print("A new", s); return ::operator new(s); }
262         static void *operator new(size_t s, void *ptr) { py::print("A placement-new", s); return ptr; }
263         static void operator delete(void *p) { py::print("A delete"); return ::operator delete(p); }
264     };
265     struct HasOpNewDelSize {
266         std::uint32_t i;
267         static void *operator new(size_t s) { py::print("B new", s); return ::operator new(s); }
268         static void *operator new(size_t s, void *ptr) { py::print("B placement-new", s); return ptr; }
269         static void operator delete(void *p, size_t s) { py::print("B delete", s); return ::operator delete(p); }
270     };
271     struct AliasedHasOpNewDelSize {
272         std::uint64_t i;
273         static void *operator new(size_t s) { py::print("C new", s); return ::operator new(s); }
274         static void *operator new(size_t s, void *ptr) { py::print("C placement-new", s); return ptr; }
275         static void operator delete(void *p, size_t s) { py::print("C delete", s); return ::operator delete(p); }
276         virtual ~AliasedHasOpNewDelSize() = default;
277         AliasedHasOpNewDelSize() = default;
278         AliasedHasOpNewDelSize(const AliasedHasOpNewDelSize&) = delete;
279     };
280     struct PyAliasedHasOpNewDelSize : AliasedHasOpNewDelSize {
281         PyAliasedHasOpNewDelSize() = default;
282         explicit PyAliasedHasOpNewDelSize(int) {}
283         std::uint64_t j;
284     };
285     struct HasOpNewDelBoth {
286         std::uint32_t i[8];
287         static void *operator new(size_t s) { py::print("D new", s); return ::operator new(s); }
288         static void *operator new(size_t s, void *ptr) { py::print("D placement-new", s); return ptr; }
289         static void operator delete(void *p) { py::print("D delete"); return ::operator delete(p); }
290         static void operator delete(void *p, size_t s) { py::print("D wrong delete", s); return ::operator delete(p); }
291     };
292     py::class_<HasOpNewDel>(m, "HasOpNewDel").def(py::init<>());
293     py::class_<HasOpNewDelSize>(m, "HasOpNewDelSize").def(py::init<>());
294     py::class_<HasOpNewDelBoth>(m, "HasOpNewDelBoth").def(py::init<>());
295     py::class_<AliasedHasOpNewDelSize, PyAliasedHasOpNewDelSize> aliased(m, "AliasedHasOpNewDelSize");
296     aliased.def(py::init<>());
297     aliased.attr("size_noalias") = py::int_(sizeof(AliasedHasOpNewDelSize));
298     aliased.attr("size_alias") = py::int_(sizeof(PyAliasedHasOpNewDelSize));
299 
300     // This test is actually part of test_local_bindings (test_duplicate_local), but we need a
301     // definition in a different compilation unit within the same module:
302     bind_local<LocalExternal, 17>(m, "LocalExternal", py::module_local());
303 
304     // test_bind_protected_functions
305     class ProtectedA {
306     protected:
307         int foo() const { return value; }
308 
309     private:
310         int value = 42;
311     };
312 
313     class PublicistA : public ProtectedA {
314     public:
315         using ProtectedA::foo;
316     };
317 
318     py::class_<ProtectedA>(m, "ProtectedA")
319         .def(py::init<>())
320 #if !defined(_MSC_VER) || _MSC_VER >= 1910
321         .def("foo", &PublicistA::foo);
322 #else
323         .def("foo", static_cast<int (ProtectedA::*)() const>(&PublicistA::foo));
324 #endif
325 
326     class ProtectedB {
327     public:
328         virtual ~ProtectedB() = default;
329         ProtectedB() = default;
330         ProtectedB(const ProtectedB &) = delete;
331 
332     protected:
333         virtual int foo() const { return value; }
334 
335     private:
336         int value = 42;
337     };
338 
339     class TrampolineB : public ProtectedB {
340     public:
341         int foo() const override { PYBIND11_OVERRIDE(int, ProtectedB, foo, ); }
342     };
343 
344     class PublicistB : public ProtectedB {
345     public:
346         // [workaround(intel)] = default does not work here
347         // Removing or defaulting this destructor results in linking errors with the Intel compiler
348         // (in Debug builds only, tested with icpc (ICC) 2021.1 Beta 20200827)
349         ~PublicistB() override {};  // NOLINT(modernize-use-equals-default)
350         using ProtectedB::foo;
351     };
352 
353     py::class_<ProtectedB, TrampolineB>(m, "ProtectedB")
354         .def(py::init<>())
355 #if !defined(_MSC_VER) || _MSC_VER >= 1910
356         .def("foo", &PublicistB::foo);
357 #else
358         .def("foo", static_cast<int (ProtectedB::*)() const>(&PublicistB::foo));
359 #endif
360 
361     // test_brace_initialization
362     struct BraceInitialization {
363         int field1;
364         std::string field2;
365     };
366 
367     py::class_<BraceInitialization>(m, "BraceInitialization")
368         .def(py::init<int, const std::string &>())
369         .def_readwrite("field1", &BraceInitialization::field1)
370         .def_readwrite("field2", &BraceInitialization::field2);
371     // We *don't* want to construct using braces when the given constructor argument maps to a
372     // constructor, because brace initialization could go to the wrong place (in particular when
373     // there is also an `initializer_list<T>`-accept constructor):
374     py::class_<NoBraceInitialization>(m, "NoBraceInitialization")
375         .def(py::init<std::vector<int>>())
376         .def_readonly("vec", &NoBraceInitialization::vec);
377 
378     // test_reentrant_implicit_conversion_failure
379     // #1035: issue with runaway reentrant implicit conversion
380     struct BogusImplicitConversion {
381         BogusImplicitConversion(const BogusImplicitConversion &) = default;
382     };
383 
384     py::class_<BogusImplicitConversion>(m, "BogusImplicitConversion")
385         .def(py::init<const BogusImplicitConversion &>());
386 
387     py::implicitly_convertible<int, BogusImplicitConversion>();
388 
389     // test_qualname
390     // #1166: nested class docstring doesn't show nested name
391     // Also related: tests that __qualname__ is set properly
392     struct NestBase {};
393     struct Nested {};
394     py::class_<NestBase> base(m, "NestBase");
395     base.def(py::init<>());
396     py::class_<Nested>(base, "Nested")
397         .def(py::init<>())
398         .def("fn", [](Nested &, int, NestBase &, Nested &) {})
399         .def("fa", [](Nested &, int, NestBase &, Nested &) {},
400                 "a"_a, "b"_a, "c"_a);
401     base.def("g", [](NestBase &, Nested &) {});
402     base.def("h", []() { return NestBase(); });
403 
404     // test_error_after_conversion
405     // The second-pass path through dispatcher() previously didn't
406     // remember which overload was used, and would crash trying to
407     // generate a useful error message
408 
409     struct NotRegistered {};
410     struct StringWrapper { std::string str; };
411     m.def("test_error_after_conversions", [](int) {});
412     m.def("test_error_after_conversions",
413           [](const StringWrapper &) -> NotRegistered { return {}; });
414     py::class_<StringWrapper>(m, "StringWrapper").def(py::init<std::string>());
415     py::implicitly_convertible<std::string, StringWrapper>();
416 
417     #if defined(PYBIND11_CPP17)
418         struct alignas(1024) Aligned {
419             std::uintptr_t ptr() const { return (uintptr_t) this; }
420         };
421         py::class_<Aligned>(m, "Aligned")
422             .def(py::init<>())
423             .def("ptr", &Aligned::ptr);
424     #endif
425 
426     // test_final
427     struct IsFinal final {};
428     py::class_<IsFinal>(m, "IsFinal", py::is_final());
429 
430     // test_non_final_final
431     struct IsNonFinalFinal {};
432     py::class_<IsNonFinalFinal>(m, "IsNonFinalFinal", py::is_final());
433 
434     // test_exception_rvalue_abort
435     struct PyPrintDestructor {
436         PyPrintDestructor() = default;
437         ~PyPrintDestructor() {
438             py::print("Print from destructor");
439         }
440         void throw_something() { throw std::runtime_error("error"); }
441     };
442     py::class_<PyPrintDestructor>(m, "PyPrintDestructor")
443         .def(py::init<>())
444         .def("throw_something", &PyPrintDestructor::throw_something);
445 
446     // test_multiple_instances_with_same_pointer
447     struct SamePointer {};
448     static SamePointer samePointer;
449     py::class_<SamePointer, std::unique_ptr<SamePointer, py::nodelete>>(m, "SamePointer")
450         .def(py::init([]() { return &samePointer; }));
451 
452     struct Empty {};
453     py::class_<Empty>(m, "Empty")
454         .def(py::init<>());
455 
456     // test_base_and_derived_nested_scope
457     struct BaseWithNested {
458         struct Nested {};
459     };
460 
461     struct DerivedWithNested : BaseWithNested {
462         struct Nested {};
463     };
464 
465     py::class_<BaseWithNested> baseWithNested_class(m, "BaseWithNested");
466     py::class_<DerivedWithNested, BaseWithNested> derivedWithNested_class(m, "DerivedWithNested");
467     py::class_<BaseWithNested::Nested>(baseWithNested_class, "Nested")
468         .def_static("get_name", []() { return "BaseWithNested::Nested"; });
469     py::class_<DerivedWithNested::Nested>(derivedWithNested_class, "Nested")
470         .def_static("get_name", []() { return "DerivedWithNested::Nested"; });
471 
472     // test_register_duplicate_class
473     struct Duplicate {};
474     struct OtherDuplicate {};
475     struct DuplicateNested {};
476     struct OtherDuplicateNested {};
477 
478     m.def("register_duplicate_class_name", [](const py::module_ &m) {
479         py::class_<Duplicate>(m, "Duplicate");
480         py::class_<OtherDuplicate>(m, "Duplicate");
481     });
482     m.def("register_duplicate_class_type", [](const py::module_ &m) {
483         py::class_<OtherDuplicate>(m, "OtherDuplicate");
484         py::class_<OtherDuplicate>(m, "YetAnotherDuplicate");
485     });
486     m.def("register_duplicate_nested_class_name", [](const py::object &gt) {
487         py::class_<DuplicateNested>(gt, "DuplicateNested");
488         py::class_<OtherDuplicateNested>(gt, "DuplicateNested");
489     });
490     m.def("register_duplicate_nested_class_type", [](const py::object &gt) {
491         py::class_<OtherDuplicateNested>(gt, "OtherDuplicateNested");
492         py::class_<OtherDuplicateNested>(gt, "YetAnotherDuplicateNested");
493     });
494 }
495 
496 template <int N> class BreaksBase { public:
497     virtual ~BreaksBase() = default;
498     BreaksBase() = default;
499     BreaksBase(const BreaksBase&) = delete;
500 };
501 template <int N> class BreaksTramp : public BreaksBase<N> {};
502 // These should all compile just fine:
503 using DoesntBreak1 = py::class_<BreaksBase<1>, std::unique_ptr<BreaksBase<1>>, BreaksTramp<1>>;
504 using DoesntBreak2 = py::class_<BreaksBase<2>, BreaksTramp<2>, std::unique_ptr<BreaksBase<2>>>;
505 using DoesntBreak3 = py::class_<BreaksBase<3>, std::unique_ptr<BreaksBase<3>>>;
506 using DoesntBreak4 = py::class_<BreaksBase<4>, BreaksTramp<4>>;
507 using DoesntBreak5 = py::class_<BreaksBase<5>>;
508 using DoesntBreak6 = py::class_<BreaksBase<6>, std::shared_ptr<BreaksBase<6>>, BreaksTramp<6>>;
509 using DoesntBreak7 = py::class_<BreaksBase<7>, BreaksTramp<7>, std::shared_ptr<BreaksBase<7>>>;
510 using DoesntBreak8 = py::class_<BreaksBase<8>, std::shared_ptr<BreaksBase<8>>>;
511 #define CHECK_BASE(N) static_assert(std::is_same<typename DoesntBreak##N::type, BreaksBase<(N)>>::value, \
512         "DoesntBreak" #N " has wrong type!")
513 CHECK_BASE(1); CHECK_BASE(2); CHECK_BASE(3); CHECK_BASE(4); CHECK_BASE(5); CHECK_BASE(6); CHECK_BASE(7); CHECK_BASE(8);
514 #define CHECK_ALIAS(N) static_assert(DoesntBreak##N::has_alias && std::is_same<typename DoesntBreak##N::type_alias, BreaksTramp<(N)>>::value, \
515         "DoesntBreak" #N " has wrong type_alias!")
516 #define CHECK_NOALIAS(N) static_assert(!DoesntBreak##N::has_alias && std::is_void<typename DoesntBreak##N::type_alias>::value, \
517         "DoesntBreak" #N " has type alias, but shouldn't!")
518 CHECK_ALIAS(1); CHECK_ALIAS(2); CHECK_NOALIAS(3); CHECK_ALIAS(4); CHECK_NOALIAS(5); CHECK_ALIAS(6); CHECK_ALIAS(7); CHECK_NOALIAS(8);
519 #define CHECK_HOLDER(N, TYPE) static_assert(std::is_same<typename DoesntBreak##N::holder_type, std::TYPE##_ptr<BreaksBase<(N)>>>::value, \
520         "DoesntBreak" #N " has wrong holder_type!")
521 CHECK_HOLDER(1, unique); CHECK_HOLDER(2, unique); CHECK_HOLDER(3, unique); CHECK_HOLDER(4, unique); CHECK_HOLDER(5, unique);
522 CHECK_HOLDER(6, shared); CHECK_HOLDER(7, shared); CHECK_HOLDER(8, shared);
523 
524 // There's no nice way to test that these fail because they fail to compile; leave them here,
525 // though, so that they can be manually tested by uncommenting them (and seeing that compilation
526 // failures occurs).
527 
528 // We have to actually look into the type: the typedef alone isn't enough to instantiate the type:
529 #define CHECK_BROKEN(N) static_assert(std::is_same<typename Breaks##N::type, BreaksBase<-(N)>>::value, \
530         "Breaks1 has wrong type!");
531 
532 //// Two holder classes:
533 //typedef py::class_<BreaksBase<-1>, std::unique_ptr<BreaksBase<-1>>, std::unique_ptr<BreaksBase<-1>>> Breaks1;
534 //CHECK_BROKEN(1);
535 //// Two aliases:
536 //typedef py::class_<BreaksBase<-2>, BreaksTramp<-2>, BreaksTramp<-2>> Breaks2;
537 //CHECK_BROKEN(2);
538 //// Holder + 2 aliases
539 //typedef py::class_<BreaksBase<-3>, std::unique_ptr<BreaksBase<-3>>, BreaksTramp<-3>, BreaksTramp<-3>> Breaks3;
540 //CHECK_BROKEN(3);
541 //// Alias + 2 holders
542 //typedef py::class_<BreaksBase<-4>, std::unique_ptr<BreaksBase<-4>>, BreaksTramp<-4>, std::shared_ptr<BreaksBase<-4>>> Breaks4;
543 //CHECK_BROKEN(4);
544 //// Invalid option (not a subclass or holder)
545 //typedef py::class_<BreaksBase<-5>, BreaksTramp<-4>> Breaks5;
546 //CHECK_BROKEN(5);
547 //// Invalid option: multiple inheritance not supported:
548 //template <> struct BreaksBase<-8> : BreaksBase<-6>, BreaksBase<-7> {};
549 //typedef py::class_<BreaksBase<-8>, BreaksBase<-6>, BreaksBase<-7>> Breaks8;
550 //CHECK_BROKEN(8);
551