Merge pull request #444 from dean0x7d/inherit-dynamic-attr
Fix dynamic attribute inheritance in C++
diff --git a/include/pybind11/attr.h b/include/pybind11/attr.h
index 15bb2e4..1ea925c 100644
--- a/include/pybind11/attr.h
+++ b/include/pybind11/attr.h
@@ -179,6 +179,9 @@
bases.append((PyObject *) base_info->type);
+ if (base_info->type->tp_dictoffset != 0)
+ dynamic_attr = true;
+
if (caster)
base_info->implicit_casts.push_back(std::make_pair(type, caster));
}
diff --git a/tests/test_methods_and_attributes.cpp b/tests/test_methods_and_attributes.cpp
index 4948dc0..c78e64b 100644
--- a/tests/test_methods_and_attributes.cpp
+++ b/tests/test_methods_and_attributes.cpp
@@ -59,6 +59,8 @@
~DynamicClass() { print_destroyed(this); }
};
+class CppDerivedDynamicClass : public DynamicClass { };
+
test_initializer methods_and_attributes([](py::module &m) {
py::class_<ExampleMandA>(m, "ExampleMandA")
.def(py::init<>())
@@ -90,4 +92,7 @@
py::class_<DynamicClass>(m, "DynamicClass", py::dynamic_attr())
.def(py::init());
+
+ py::class_<CppDerivedDynamicClass, DynamicClass>(m, "CppDerivedDynamicClass")
+ .def(py::init());
});
diff --git a/tests/test_methods_and_attributes.py b/tests/test_methods_and_attributes.py
index 04f2d12..1c7b3da 100644
--- a/tests/test_methods_and_attributes.py
+++ b/tests/test_methods_and_attributes.py
@@ -48,7 +48,7 @@
def test_dynamic_attributes():
- from pybind11_tests import DynamicClass
+ from pybind11_tests import DynamicClass, CppDerivedDynamicClass
instance = DynamicClass()
assert not hasattr(instance, "foo")
@@ -76,16 +76,17 @@
assert cstats.alive() == 0
# Derived classes should work as well
- class Derived(DynamicClass):
+ class PythonDerivedDynamicClass(DynamicClass):
pass
- derived = Derived()
- derived.foobar = 100
- assert derived.foobar == 100
+ for cls in CppDerivedDynamicClass, PythonDerivedDynamicClass:
+ derived = cls()
+ derived.foobar = 100
+ assert derived.foobar == 100
- assert cstats.alive() == 1
- del derived
- assert cstats.alive() == 0
+ assert cstats.alive() == 1
+ del derived
+ assert cstats.alive() == 0
def test_cyclic_gc():