diff --git a/include/aidge/utils/Attributes.hpp b/include/aidge/utils/Attributes.hpp index d3444000191022b575adaf1430319479daa5d4fc..927686cfd5cca910c5ffb25364ae4bc971ad18bf 100644 --- a/include/aidge/utils/Attributes.hpp +++ b/include/aidge/utils/Attributes.hpp @@ -69,6 +69,11 @@ public: * be agnostic from its return type. */ virtual py::object getAttrPy(const std::string& name) const = 0; + /* Bindable set function, does not recquire any templating. + * This is thanks to py::object which allow the function to + * be agnostic from ``value`` type. + */ + virtual void setAttrPy(const std::string& name, py::object&& value) = 0; #endif virtual ~Attributes() {} }; diff --git a/include/aidge/utils/DynamicAttributes.hpp b/include/aidge/utils/DynamicAttributes.hpp index 2af8f47e9420f266cc6eca21f167944c761db7ea..44c3b1f5e8df833344fa9b7fe72bdb4ef1e0ec12 100644 --- a/include/aidge/utils/DynamicAttributes.hpp +++ b/include/aidge/utils/DynamicAttributes.hpp @@ -135,7 +135,7 @@ public: assert(res.second && "attribute already exists"); } - void setAttrPy(const std::string& name, py::object&& value) + void setAttrPy(const std::string& name, py::object&& value) override final { auto resPy = mAttrsPy.emplace(std::make_pair(name, value)); if (!resPy.second) @@ -204,7 +204,7 @@ private: // Stores C++ attributes (copy) and Python-only attributes // Code should be compiled with -fvisibility=hidden // See https://pybind11.readthedocs.io/en/stable/faq.html: - // “‘SomeClass’ declared with greater visibility than the type of its + // “‘SomeClass’ declared with greater visibility than the type of its // field ‘SomeClass::member’ [-Wattributes]†// This map will only be populated if Python interpreter is running std::map<std::string, py::object> mAttrsPy; diff --git a/include/aidge/utils/StaticAttributes.hpp b/include/aidge/utils/StaticAttributes.hpp index a90a08b01915c461bc8951c08ee2dbd979b957de..fa450769f2fb0958f03a12623f1e9455ed60797f 100644 --- a/include/aidge/utils/StaticAttributes.hpp +++ b/include/aidge/utils/StaticAttributes.hpp @@ -212,7 +212,22 @@ public: } AIDGE_THROW_OR_ABORT(py::value_error, "attribute \"%s\" not found", name.c_str()); - }; + } + + + void setAttrPy(const std::string& name, py::object&& value) override final{ + for (std::size_t i = 0; i < size(EnumStrings<ATTRS_ENUM>::data); ++i) { + if (name == EnumStrings<ATTRS_ENUM>::data[i]) { + // Cannot update attribute using reference has it would require templating + // Use a dirty + auto tmpAttr = py::cast(mAttrs); + py::detail::accessor_policies::tuple_item::set(tmpAttr, static_cast<py::size_t>(i), value); + mAttrs = py::cast<std::tuple<T...>>(tmpAttr); + return; + } + } + AIDGE_THROW_OR_ABORT(py::value_error, "attribute \"%s\" not found", name.c_str()); + } #endif private: diff --git a/python_binding/utils/pybind_Parameter.cpp b/python_binding/utils/pybind_Parameter.cpp index 2957876f31ad0781a36905cef3a5ae88934b6a8a..056cbf16b491a40c40dee16d2ed891c4974a53dc 100644 --- a/python_binding/utils/pybind_Parameter.cpp +++ b/python_binding/utils/pybind_Parameter.cpp @@ -21,7 +21,8 @@ void init_Attributes(py::module& m){ .def("has_attr", &Attributes::hasAttr, py::arg("name")) .def("get_attr_type", &Attributes::getAttrType, py::arg("name")) .def("get_attrs_name", &Attributes::getAttrsName) - .def("get_attr", &Attributes::getAttrPy, py::arg("name")); + .def("get_attr", &Attributes::getAttrPy, py::arg("name")) + .def("set_attr", &Attributes::setAttrPy, py::arg("name"), py::arg("value")); py::class_<DynamicAttributes, std::shared_ptr<DynamicAttributes>, Attributes>(m, "DynamicAttributes") .def("add_attr", &DynamicAttributes::addAttrPy, py::arg("name"), py::arg("value"))