Description
I would like to add dynamic attributes to objects stored as shared pointers in std::vector's. I have read the docs and I'm still not sure whether this is truly possible or no. However, while performing some tests I have discovered an inconsistency that pybind11 devs might be interested in.
This inconsistent behaviour can be reproduced with the following c++ code:
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <vector>
#include <memory>
namespace py = pybind11;
class Foo {
public:
Foo() {}
~Foo() {}
};
class Bar {
public:
Bar() {
foos.push_back(std::make_shared<Foo>());
}
~Bar() {}
std::vector<std::shared_ptr<Foo>> foos;
};
PYBIND11_MODULE(pybug, m) {
py::class_<Foo, std::shared_ptr<Foo>> foo(m, "Foo", py::dynamic_attr());
foo
.def(py::init<>());
py::class_<Bar> bar(m, "Bar");
bar
.def(py::init<>())
.def_readwrite("foos", &Bar::foos);
}
which can be compiled (at least on my Linux box) with
g++ pybug.cpp -shared --std=c++11 -fPIC `python3 -m pybind11 --includes` -o pybug`python3-config --extension-suffix`
Now, on the python side the following snippet works or not depending whether the line starting with myfoo
is commented or not:
import pybug
bar = pybug.Bar()
myfoo = bar.foos[0] # if this line is commented out then the subsequent print line will raise an "AttributeError"
bar.foos[0].b = 2
print(bar.foos[0].b)
Is there some hidden caching going on here (as suggested by this answer)? Is it possible to add dynamic attributes to the instances stored in the foos
vector without keeping an explicit reference to each of them?