diff --git a/include/aidge/utils/DynamicAttributes.hpp b/include/aidge/utils/DynamicAttributes.hpp
index 8ee294ce3a1bfa8bc95e0896794511b4c59822d4..41e2da94050357ae624525b31175ffab2e046acf 100644
--- a/include/aidge/utils/DynamicAttributes.hpp
+++ b/include/aidge/utils/DynamicAttributes.hpp
@@ -44,7 +44,7 @@ public:
      *  exist
      * \note at() throws if the Attribute does not exist, using find to test for Attribute existance
      */
-    template<class T> T getAttr(const std::string& name) const
+    template<class T> T& getAttr(const std::string& name)
     {
 #ifdef PYBIND
         // If attribute does not exist in C++, it might have been created in Python
@@ -52,16 +52,16 @@ public:
         if (it == mAttrs.end()) {
             auto itPy = mAttrsPy.find(name);
             if (itPy != mAttrsPy.end()) {
-                return itPy->second.cast<T>();
+                // Insert the attribute back in C++
+                mAttrs.emplace(std::make_pair(name, libany::any(itPy->second.cast<T>())));
             }
         }
 #endif
 
-        return libany::any_cast<T>(mAttrs.at(name));
+        return libany::any_cast<T&>(mAttrs.at(name));
     }
 
     // Note: return by reference is not possible because py::object::cast() returns a temporary
-/*
     template<class T> const T& getAttr(const std::string& name) const
     {
 #ifdef PYBIND
@@ -70,14 +70,15 @@ public:
         if (it == mAttrs.end()) {
             auto itPy = mAttrsPy.find(name);
             if (itPy != mAttrsPy.end()) {
-                return itPy->second.cast<T>();
+                // Insert the attribute back in C++
+                mAttrs.emplace(std::make_pair(name, libany::any(itPy->second.cast<T>())));
             }
         }
 #endif
 
         return libany::any_cast<const T&>(mAttrs.at(name));
     }
-*/
+
     ///\brief Add a new Attribute, identified by its name. If it already exists, asserts.
     ///\tparam T expected Attribute type
     ///\param name Attribute name
@@ -178,9 +179,6 @@ public:
 #endif
 
 private:
-    // Stores C++ attributes only
-    std::map<std::string, libany::any> mAttrs;
-
 #ifdef PYBIND
     // Stores C++ attributes (copy) and Python-only attributes
     // Code should be compiled with -fvisibility=hidden
@@ -188,6 +186,11 @@ private:
     // “‘SomeClass’ declared with greater visibility than the type of its 
     // field ‘SomeClass::member’ [-Wattributes]”
     std::map<std::string, py::object> mAttrsPy;
+    // Stores C++ attributes only
+    // mutable because it may be updated in getAttr() from Python
+    mutable std::map<std::string, libany::any> mAttrs;
+#else
+    std::map<std::string, libany::any> mAttrs;
 #endif
 };