Open
Description
Required prerequisites
- Make sure you've read the documentation. Your issue may be addressed there.
- Search the issue tracker and Discussions to verify that this hasn't already been reported. +1 or comment there if it has.
- Consider asking first in the Gitter chat room or in a Discussion.
Problem description
In the binding code below __getattr__
will only be found in the derived class if we do:
py::class_<Derived, Base, OtherBase>(m, "Derived")
if we instead do:
py::class_<Derived, OtherBase, Base>(m, "Derived")
note the order of the base classes switched,
the bound __getattr__
will never be called.
From what I understand from the documentation (https://pybind11.readthedocs.io/en/latest/advanced/classes.html#multiple-inheritance) the order of the base classes should not matter?
This is tested with the latest master as of writing.
Reproducible example code
// binding code
#include <pybind11/pybind11.h>
namespace py = pybind11;
struct Base {
virtual ~Base() = default;
int base() const { return 0; }
};
struct OtherBase {
int other() const { return 3; }
};
struct Derived : Base, OtherBase{
int id() const { return 2; }
};
PYBIND11_MODULE(bar, m) {
py::class_<Base>(m, "Base")
.def(py::init<>())
.def("base", &Base::base)
.def("__getattr__", [](Base&, std::string key) {
return "Base GetAttr: " + key;
});
py::class_<OtherBase>(m, "OtherBase")
.def("other", &OtherBase::other);
py::class_<Derived, OtherBase, Base>(m, "Derived")
.def(py::init<>())
.def("id", &Derived::id);
}
// test code
import bar
d = bar.Derived()
print(f"d.base(): {d.base()}")
print(f"d.other(): {d.other()}")
print(f"d.id(): {d.id()}")
print(f"d.prop: {d.prop}") # this will fail (if Base is not the first base class)