Make all classes with the same instance size derive from a common base

In order to fully satisfy Python's inheritance type layout requirements,
all types should have a common 'solid' base. A solid base is one which
has the same instance size as the derived type (not counting the space
required for the optional `dict_ptr` and `weakrefs_ptr`). Thus, `object`
does not qualify as a solid base for pybind11 types and this can lead to
issues with multiple inheritance.

To get around this, new base types are created: one per unique instance
size. There is going to be very few of these bases. They ensure Python's
MRO checks will pass when multiple bases are involved.
This commit is contained in:
Dean Moldovan
2017-02-15 21:10:25 +01:00
committed by Wenzel Jakob
parent c91f8bd627
commit 08cbe8dfed
8 changed files with 509 additions and 274 deletions

View File

@@ -36,6 +36,10 @@ public:
Hamster(const std::string &name) : Pet(name, "rodent") {}
};
class Chimera : public Pet {
Chimera() : Pet("Kimmy", "chimera") {}
};
std::string pet_name_species(const Pet &pet) {
return pet.name() + " is a " + pet.species();
}
@@ -74,6 +78,8 @@ test_initializer inheritance([](py::module &m) {
py::class_<Hamster, Pet>(m, "Hamster")
.def(py::init<std::string>());
py::class_<Chimera, Pet>(m, "Chimera");
m.def("pet_name_species", pet_name_species);
m.def("dog_bark", dog_bark);