Allow passing base types as a template parameter
This allows a slightly cleaner base type specification of:
py::class_<Type, Base>("Type")
as an alternative to
py::class_<Type>("Type", py::base<Base>())
As with the other template parameters, the order relative to the holder
or trampoline types doesn't matter.
This also includes a compile-time assertion failure if attempting to
specify more than one base class (but is easily extendible to support
multiple inheritance, someday, by updating the class_selector::set_bases
function to set multiple bases).
diff --git a/tests/test_inheritance.cpp b/tests/test_inheritance.cpp
index e1aad99..798beff 100644
--- a/tests/test_inheritance.cpp
+++ b/tests/test_inheritance.cpp
@@ -31,6 +31,11 @@
Rabbit(const std::string &name) : Pet(name, "parrot") {}
};
+class Hamster : public Pet {
+public:
+ Hamster(const std::string &name) : Pet(name, "rodent") {}
+};
+
std::string pet_name_species(const Pet &pet) {
return pet.name() + " is a " + pet.species();
}
@@ -59,6 +64,10 @@
py::class_<Rabbit>(m, "Rabbit", py::base<Pet>())
.def(py::init<std::string>());
+ /* And another: list parent in class template arguments */
+ py::class_<Hamster, Pet>(m, "Hamster")
+ .def(py::init<std::string>());
+
m.def("pet_name_species", pet_name_species);
m.def("dog_bark", dog_bark);
diff --git a/tests/test_inheritance.py b/tests/test_inheritance.py
index b55490c..d4cea82 100644
--- a/tests/test_inheritance.py
+++ b/tests/test_inheritance.py
@@ -2,7 +2,7 @@
def test_inheritance(msg):
- from pybind11_tests import Pet, Dog, Rabbit, dog_bark, pet_name_species
+ from pybind11_tests import Pet, Dog, Rabbit, Hamster, dog_bark, pet_name_species
roger = Rabbit('Rabbit')
assert roger.name() + " is a " + roger.species() == "Rabbit is a parrot"
@@ -16,6 +16,9 @@
assert molly.name() + " is a " + molly.species() == "Molly is a dog"
assert pet_name_species(molly) == "Molly is a dog"
+ fred = Hamster('Fred')
+ assert fred.name() + " is a " + fred.species() == "Fred is a rodent"
+
assert dog_bark(molly) == "Woof!"
with pytest.raises(TypeError) as excinfo:
diff --git a/tests/test_issues.cpp b/tests/test_issues.cpp
index 0a5a0b0..55502fe 100644
--- a/tests/test_issues.cpp
+++ b/tests/test_issues.cpp
@@ -96,7 +96,7 @@
py::class_<ElementBase, std::shared_ptr<ElementBase>> (m2, "ElementBase");
- py::class_<ElementA, std::shared_ptr<ElementA>>(m2, "ElementA", py::base<ElementBase>())
+ py::class_<ElementA, ElementBase, std::shared_ptr<ElementA>>(m2, "ElementA")
.def(py::init<int>())
.def("value", &ElementA::value);
diff --git a/tests/test_virtual_functions.cpp b/tests/test_virtual_functions.cpp
index ac5b3fb..381b87e 100644
--- a/tests/test_virtual_functions.cpp
+++ b/tests/test_virtual_functions.cpp
@@ -258,12 +258,12 @@
.def("unlucky_number", &A_Repeat::unlucky_number)
.def("say_something", &A_Repeat::say_something)
.def("say_everything", &A_Repeat::say_everything);
- py::class_<B_Repeat, PyB_Repeat>(m, "B_Repeat", py::base<A_Repeat>())
+ py::class_<B_Repeat, A_Repeat, PyB_Repeat>(m, "B_Repeat")
.def(py::init<>())
.def("lucky_number", &B_Repeat::lucky_number);
- py::class_<C_Repeat, PyC_Repeat>(m, "C_Repeat", py::base<B_Repeat>())
+ py::class_<C_Repeat, B_Repeat, PyC_Repeat>(m, "C_Repeat")
.def(py::init<>());
- py::class_<D_Repeat, PyD_Repeat>(m, "D_Repeat", py::base<C_Repeat>())
+ py::class_<D_Repeat, C_Repeat, PyD_Repeat>(m, "D_Repeat")
.def(py::init<>());
// Method 2: Templated trampolines
@@ -272,12 +272,12 @@
.def("unlucky_number", &A_Tpl::unlucky_number)
.def("say_something", &A_Tpl::say_something)
.def("say_everything", &A_Tpl::say_everything);
- py::class_<B_Tpl, PyB_Tpl<>>(m, "B_Tpl", py::base<A_Tpl>())
+ py::class_<B_Tpl, A_Tpl, PyB_Tpl<>>(m, "B_Tpl")
.def(py::init<>())
.def("lucky_number", &B_Tpl::lucky_number);
- py::class_<C_Tpl, PyB_Tpl<C_Tpl>>(m, "C_Tpl", py::base<B_Tpl>())
+ py::class_<C_Tpl, B_Tpl, PyB_Tpl<C_Tpl>>(m, "C_Tpl")
.def(py::init<>());
- py::class_<D_Tpl, PyB_Tpl<D_Tpl>>(m, "D_Tpl", py::base<C_Tpl>())
+ py::class_<D_Tpl, C_Tpl, PyB_Tpl<D_Tpl>>(m, "D_Tpl")
.def(py::init<>());
};