diff --git a/SDK/CPP/public/python/README.md b/SDK/CPP/public/python/README.md
index 52773c98c80059795aed630660c4c882de90c671..076ec86e3fca27d3778ba90522dc39cead275fba 100644
--- a/SDK/CPP/public/python/README.md
+++ b/SDK/CPP/public/python/README.md
@@ -16,10 +16,9 @@ build. Several (empty) macros are used in headers to annoate Python API details.
  * PY_API function/method is to be included in Python API
  * PY_NO_SHARED_PTR shared_ptr<> is not used with instances of this class.
    See [pybind11 documentation](https://pybind11.readthedocs.io/en/latest/advanced/smart_ptrs.html?#std-shared-ptr)
-   for techncal details.
+   for techncal details. Shared pointers are not used for structs.
  * PY_RV_LIFETIME_PARENT lifetime of method's return valued is tied to
-   lifetime of parent objects (this). (
-   [return_value_policy::reference_internal](https://pybind11.readthedocs.io/en/latest/advanced/functions.html#return-value-policies)
+   lifetime of parent objects (this). ([return_value_policy::reference_internal](https://pybind11.readthedocs.io/en/latest/advanced/functions.html#return-value-policies)
    is set for this method)
  * PY_SINGLETON Singleton class, methods are exported to to module scope.
  * PY_SINGLETON_OBJECT Singleton instance is accessible as module attribute.
diff --git a/SDK/CPP/public/python/gen.py b/SDK/CPP/public/python/gen.py
index 649b45b6f69f731ff38c9c0a833b7c0fd8b27474..c284c737e5077419463bb498cf7a82bc25cb303f 100755
--- a/SDK/CPP/public/python/gen.py
+++ b/SDK/CPP/public/python/gen.py
@@ -37,7 +37,6 @@ def read_line(file, lineno):
             if i == lineno:
                 return line
 
-
 def get_loc_msg(data):
     return "({0}:{1})".format(data["filename"], data["line_number"])
 
@@ -54,6 +53,9 @@ def print_err(msg, loc=None):
 def include_in_api(data):
     return "PY_API" in data["debug"]
 
+def no_shared_ptr_cls(clsdata):
+    return (clsdata["declaration_method"] == "struct") or ("PY_NO_SHARED_PTR" in clsdata["debug"])
+
 def create_enum_bindigs(enum, parent=[], pybind_handle="", export_values=False):
     name_full = parent + [enum["name"]]
     name_py = enum["name"]
@@ -144,27 +146,28 @@ def create_function_bindings(func, parent=[], pybind_handle=None, bind_to_single
 
     return cpp
 
-def create_class_bindings(cls, parent=[], pybind_handle=""):
+def create_class_bindings(clsdata, parent=[], pybind_handle=""):
     """ Create bindings for a class """
 
-    cls_name = cls["name"]
-    full_name = parent + [cls_name]
+    clsdata_name = clsdata["name"]
+    full_name = parent + [clsdata_name]
     cpp = []
 
-    if "PY_NO_SHARED_PTR" not in cls["debug"]:
-        cls_cpp = "py::class_<{name}, std::shared_ptr<{name}>>({handle}, \"{name}\")"
-    else:
+    if no_shared_ptr_cls(clsdata):
         cls_cpp = "py::class_<{name}>({handle}, \"{name}\")"
-    cpp.append(cls_cpp.format(handle=pybind_handle, name=cls_name))
+    else:
+        cls_cpp = "py::class_<{name}, std::shared_ptr<{name}>>({handle}, \"{name}\")"
+
+    cpp.append(cls_cpp.format(handle=pybind_handle, name=clsdata_name))
 
-    if cls["declaration_method"] == "struct":
+    if clsdata["declaration_method"] == "struct":
         cpp.append(".def(py::init<>())")
 
-    for method in cls["methods"]["public"]:
+    for method in clsdata["methods"]["public"]:
         if include_in_api(method):
             cpp.append("." + create_function_bindings(method, full_name))
 
-    for field in cls["properties"]["public"]:
+    for field in clsdata["properties"]["public"]:
         if field["constant"]:
             field_cpp = ".def_property_readonly(\"{name}\", &{cpp_name})"
         else:
@@ -175,7 +178,7 @@ def create_class_bindings(cls, parent=[], pybind_handle=""):
 
     return "\n\t\t".join(cpp)
 
-def create_singleton_bindings(instance_ptr, cls, parent=[], pybind_handle="", export=False):
+def create_singleton_bindings(instance_ptr, clsdata, parent=[], pybind_handle="", export=False):
     """ Singleton class bindings, either creates a singleton instance or
     exports functions directly to module. Singleton pointer available with
     instance_ptr, which should be class member of PyModule.
@@ -183,14 +186,14 @@ def create_singleton_bindings(instance_ptr, cls, parent=[], pybind_handle="", ex
     if not export:
         # use usual bindings and export as attribute to pybind handle
         return "\n\t".join([
-            create_class_bindings(cls, parent, pybind_handle) + ";",
-            "{0}.attr(\"{1}\") = {2};".format(pybind_handle, cls["name"], instance_ptr)
+            create_class_bindings(clsdata, parent, pybind_handle) + ";",
+            "{0}.attr(\"{1}\") = {2};".format(pybind_handle, clsdata["name"], instance_ptr)
         ])
 
     else:
         # use C++ lambdas to wrap all methods
         cpp = []
-        for func in cls["methods"]["public"]:
+        for func in clsdata["methods"]["public"]:
             if not include_in_api(func):
                 continue