bt2: pass custom Python object to Python component's __init__()
[babeltrace.git] / src / bindings / python / bt2 / bt2 / native_bt_component_class.i.h
index fc10efef34b6bff60ab069c7075a43c5930703a2..9b1e7d279292564fd9935a1ee79ab00ce9cda876 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include "logging/comp-logging.h"
+#include "compat/glib.h"
 
 /*
  * This hash table associates a BT component class object address to a
@@ -183,6 +184,12 @@ int py_exc_to_status_message_iterator(
        return py_exc_to_status(NULL, NULL, self_message_iterator, NULL, -1);
 }
 
+static
+bool bt_bt2_is_python_component_class(const bt_component_class *comp_cls)
+{
+       return bt_g_hash_table_contains(bt_cc_ptr_to_py_cls, comp_cls);
+}
+
 /* Component class proxy methods (delegate to the attached Python object) */
 
 static
@@ -203,12 +210,18 @@ bt_component_class_init_method_status component_class_init(
        bt_logging_level log_level = get_self_component_log_level(
                self_component);
 
-       (void) init_method_data;
-
        BT_ASSERT(self_component);
        BT_ASSERT(self_component_v);
        BT_ASSERT(self_comp_cls_type_swig_type);
 
+       /*
+        * If there's any `init_method_data`, assume this component is
+        * getting initialized from Python, so that `init_method_data`
+        * is a Python object to pass to the user's __init__() method.
+        */
+       BT_ASSERT(!init_method_data ||
+                       bt_bt2_is_python_component_class(component_class));
+
        /*
         * Get the user-defined Python class which created this
         * component's class in the first place (borrowed
@@ -242,13 +255,21 @@ bt_component_class_init_method_status component_class_init(
        /*
         * Do the equivalent of this:
         *
-        *     py_comp = py_cls._bt_init_from_native(py_comp_ptr, py_params_ptr)
+        *     py_comp = py_cls._bt_init_from_native(py_comp_ptr,
+        *         py_params_ptr, init_method_data ? init_method_data : Py_None)
         *
         * _UserComponentType._bt_init_from_native() calls the Python
         * component object's __init__() function.
+        *
+        * We don't take any reference on `init_method_data` which, if
+        * not `NULL`, is assumed to be a `PyObject *`: the user's
+        * __init__() function will eventually take a reference if
+        * needed. If `init_method_data` is `NULL`, then we pass
+        * `Py_None` as the initialization's Python object.
         */
        py_comp = PyObject_CallMethod(py_cls,
-               "_bt_init_from_native", "(OO)", py_comp_ptr, py_params_ptr);
+               "_bt_init_from_native", "(OOO)", py_comp_ptr, py_params_ptr,
+               init_method_data ? init_method_data : Py_None);
        if (!py_comp) {
                BT_COMP_LOG_CUR_LVL(BT_LOG_WARNING, log_level, self_component,
                        "Failed to call Python class's _bt_init_from_native() method: "
This page took 0.026312 seconds and 4 git commands to generate.