mirror of
https://github.com/pybind/pybind11.git
synced 2025-02-16 21:57:55 +00:00
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:
parent
5c13749aea
commit
b8cb5ca7bd
@ -179,6 +179,9 @@ struct type_record {
|
|||||||
|
|
||||||
bases.append((PyObject *) base_info->type);
|
bases.append((PyObject *) base_info->type);
|
||||||
|
|
||||||
|
if (base_info->type->tp_dictoffset != 0)
|
||||||
|
dynamic_attr = true;
|
||||||
|
|
||||||
if (caster)
|
if (caster)
|
||||||
base_info->implicit_casts.push_back(std::make_pair(type, caster));
|
base_info->implicit_casts.push_back(std::make_pair(type, caster));
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,8 @@ public:
|
|||||||
~DynamicClass() { print_destroyed(this); }
|
~DynamicClass() { print_destroyed(this); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CppDerivedDynamicClass : public DynamicClass { };
|
||||||
|
|
||||||
test_initializer methods_and_attributes([](py::module &m) {
|
test_initializer methods_and_attributes([](py::module &m) {
|
||||||
py::class_<ExampleMandA>(m, "ExampleMandA")
|
py::class_<ExampleMandA>(m, "ExampleMandA")
|
||||||
.def(py::init<>())
|
.def(py::init<>())
|
||||||
@ -90,4 +92,7 @@ test_initializer methods_and_attributes([](py::module &m) {
|
|||||||
|
|
||||||
py::class_<DynamicClass>(m, "DynamicClass", py::dynamic_attr())
|
py::class_<DynamicClass>(m, "DynamicClass", py::dynamic_attr())
|
||||||
.def(py::init());
|
.def(py::init());
|
||||||
|
|
||||||
|
py::class_<CppDerivedDynamicClass, DynamicClass>(m, "CppDerivedDynamicClass")
|
||||||
|
.def(py::init());
|
||||||
});
|
});
|
||||||
|
@ -48,7 +48,7 @@ def test_methods_and_attributes():
|
|||||||
|
|
||||||
|
|
||||||
def test_dynamic_attributes():
|
def test_dynamic_attributes():
|
||||||
from pybind11_tests import DynamicClass
|
from pybind11_tests import DynamicClass, CppDerivedDynamicClass
|
||||||
|
|
||||||
instance = DynamicClass()
|
instance = DynamicClass()
|
||||||
assert not hasattr(instance, "foo")
|
assert not hasattr(instance, "foo")
|
||||||
@ -76,16 +76,17 @@ def test_dynamic_attributes():
|
|||||||
assert cstats.alive() == 0
|
assert cstats.alive() == 0
|
||||||
|
|
||||||
# Derived classes should work as well
|
# Derived classes should work as well
|
||||||
class Derived(DynamicClass):
|
class PythonDerivedDynamicClass(DynamicClass):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
derived = Derived()
|
for cls in CppDerivedDynamicClass, PythonDerivedDynamicClass:
|
||||||
derived.foobar = 100
|
derived = cls()
|
||||||
assert derived.foobar == 100
|
derived.foobar = 100
|
||||||
|
assert derived.foobar == 100
|
||||||
|
|
||||||
assert cstats.alive() == 1
|
assert cstats.alive() == 1
|
||||||
del derived
|
del derived
|
||||||
assert cstats.alive() == 0
|
assert cstats.alive() == 0
|
||||||
|
|
||||||
|
|
||||||
def test_cyclic_gc():
|
def test_cyclic_gc():
|
||||||
|
Loading…
Reference in New Issue
Block a user