Can't expose properties of objects deriving from BaseObject
I am creating my own custom types for SOFA, mainly some forcefields but also other stuff. In order to add those types to an object, they must inherit from Sofa.Core.Object on python. This is problematic, since Sofa.Core.Base overrides how properties are read and written. In the end, this breaks adding new properties to custom defined types that are exposed to python.
using Inherit = sofa::core::objectmodel::BaseObject;
using CG = VNCS::ConjugateGradientSolver;
::py::class_<CG, Inherit, sofa::core::sptr<CG>>(m, "ConjugateGradient")
.def(::py::init([]() { return sofa::core::objectmodel::New<CG>(); }))
.def_property(
"iterations",
[](const CG &cg) { return cg.iterations(); },
[](CG &cg, int iterations) { cg.setIterations(iterations); })
.def("setIterations", [](CG &cg, int iterations) { cg.setIterations(iterations); })
.def_property("tolerance", &CG::toleranceThreshold, &CG::setToleranceThreshold);
With that class exposed to python, it is not possible to do
cgSolver = myModule.ConjugateGradient
cgSolver.iterations = 50 # Doesn't work
print(cgSolver.iterations) # prints 25, the default value in the C++ class
This is the output for some tests
cgSolver = PyVNCS.ConjugateGradient()
dir(cgSolver)
['bbox', 'componentState', 'listening', 'name', 'printLog', 'tags']
cgSolver.iterations = 60
cgSolver.iterations
25
cgSolver.setIterations(40)
None
cgSolver.iterations
40
getattr(cgSolver, 'iterations')
40
setattr(cgSolver, 'iterations', 60)
None
getattr(cgSolver, 'iterations')
40
If ConjugateGradient doesn't inherit from Sofa.Core.Object, then the properties work fine, but I can't add it to a node.
https://github.com/sofa-framework/SofaPython3/blob/a427fa05f9dd91c3f58f532083778d4e0a7dea92/bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Base.cpp#L126
Actually, what is happening is that BaseBinding reimplements the _setattr__ function and if it doesn't find the property as a Data, it relies on adding a new dynamic one the __dict__. Before adding it as a dynamic one, it should check if the property is a python property.