Fix dynamic attribute inheritance in C++

`PyType_Ready` would usually perform the inheritance for us, but it
can't adjust `tp_basicsize` appropriately.
This commit is contained in:
Dean Moldovan 2016-10-14 18:01:17 +02:00
parent 5c13749aea
commit b8cb5ca7bd
3 changed files with 17 additions and 8 deletions

View File

@ -179,6 +179,9 @@ struct type_record {
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));
}

View File

@ -59,6 +59,8 @@ public:
~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 @@ test_initializer methods_and_attributes([](py::module &m) {
py::class_<DynamicClass>(m, "DynamicClass", py::dynamic_attr())
.def(py::init());
py::class_<CppDerivedDynamicClass, DynamicClass>(m, "CppDerivedDynamicClass")
.def(py::init());
});

View File

@ -48,7 +48,7 @@ def test_methods_and_attributes():
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 @@ def test_dynamic_attributes():
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():