From 66964f3f7b0b7e3b774ddb043b0f197018d23730 Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Sat, 3 Aug 2019 14:36:42 -0400 Subject: [PATCH] bt2: pass custom Python object to Python component's __init__() Just like you can pass custom data (`void *`) to the initialization function of a component class written in C with the bt_graph_add_*_component_with_init_method_data() functions, this patch makes it possible to pass any Python object to the __init__() method of a component class written in Python with the Graph.add_component() method. This patch installs a mechanism to share Python data between a Python graph user and the methods of a Python component without relying on `nonlocal`, global variables, or other such hacks. This data can be as simple as an integer and as complex as a database connection, for example. The __init__() method of a Python component used to look like: def __init__(self, params): ... It's now: def __init__(self, params, obj): ... When you pass any Python object to Graph.add_component() as its `obj` parameter, the Python component's __init__() method eventually receives it. Graph.add_component() ensures that the component class to instantiate is a Python component class if `obj` is not `None`. Internally, `None` gets converted to `NULL` as the `init_method_data` parameter of the bt_graph_add_*_component_with_init_method_data() functions, and then `NULL` gets converted back to `Py_None` in component_class_init(). Now there is the risk that you call bt_graph_add_*_component_with_init_method_data() in C with a Python component class and pass a non-`NULL`, non-`PyObject *` `init_method_data` parameter. However I consider an insignificant drawback as you're not supposed to use the `init_method_data` with a component class you don't know. Signed-off-by: Philippe Proulx Change-Id: Ib879ece9e423b3495b9449ca73674082020865c5 Reviewed-on: https://review.lttng.org/c/babeltrace/+/1815 Tested-by: jenkins Reviewed-by: Simon Marchi --- src/bindings/python/bt2/bt2/component.py | 6 +- src/bindings/python/bt2/bt2/graph.py | 23 +++-- .../bt2/bt2/native_bt_component_class.i | 1 + .../bt2/bt2/native_bt_component_class.i.h | 29 +++++- src/bindings/python/bt2/bt2/native_bt_graph.i | 25 ++++++ .../python/bt2/bt2/native_bt_graph.i.h | 42 +++++++++ .../bt2/trace_collection_message_iterator.py | 8 +- tests/bindings/python/bt2/test_clock_class.py | 2 +- tests/bindings/python/bt2/test_component.py | 8 +- tests/bindings/python/bt2/test_connection.py | 12 +-- tests/bindings/python/bt2/test_error.py | 8 +- tests/bindings/python/bt2/test_event.py | 2 +- tests/bindings/python/bt2/test_graph.py | 88 +++++++++++++----- tests/bindings/python/bt2/test_message.py | 2 +- .../python/bt2/test_message_iterator.py | 24 ++--- tests/bindings/python/bt2/test_port.py | 90 +++++++++---------- tests/bindings/python/bt2/utils.py | 2 +- .../bt_plugin_test.py | 6 +- .../bt_plugin_trimmer_test.py | 2 +- 19 files changed, 262 insertions(+), 118 deletions(-) diff --git a/src/bindings/python/bt2/bt2/component.py b/src/bindings/python/bt2/bt2/component.py index 31f63725..8052e8a4 100644 --- a/src/bindings/python/bt2/bt2/component.py +++ b/src/bindings/python/bt2/bt2/component.py @@ -508,7 +508,7 @@ class _UserComponentType(type): cls._bt_cc_ptr = cc_ptr - def _bt_init_from_native(cls, comp_ptr, params_ptr): + def _bt_init_from_native(cls, comp_ptr, params_ptr, obj): # create instance, not user-initialized yet self = cls.__new__(cls) @@ -521,7 +521,7 @@ class _UserComponentType(type): else: params = None - self.__init__(params) + self.__init__(params, obj) return self def __call__(cls, *args, **kwargs): @@ -659,7 +659,7 @@ class _UserComponent(metaclass=_UserComponentType): def addr(self): return int(self._bt_ptr) - def __init__(self, params=None): + def __init__(self, params=None, obj=None): pass def _user_finalize(self): diff --git a/src/bindings/python/bt2/bt2/graph.py b/src/bindings/python/bt2/bt2/graph.py index aa6b8a74..b8cdb1f4 100644 --- a/src/bindings/python/bt2/bt2/graph.py +++ b/src/bindings/python/bt2/bt2/graph.py @@ -84,31 +84,32 @@ class Graph(object._SharedObject): component_class, name, params=None, + obj=None, logging_level=bt2_logging.LoggingLevel.NONE, ): if isinstance(component_class, bt2_component._SourceComponentClass): cc_ptr = component_class._ptr - add_fn = native_bt.graph_add_source_component + add_fn = native_bt.bt2_graph_add_source_component cc_type = native_bt.COMPONENT_CLASS_TYPE_SOURCE elif isinstance(component_class, bt2_component._FilterComponentClass): cc_ptr = component_class._ptr - add_fn = native_bt.graph_add_filter_component + add_fn = native_bt.bt2_graph_add_filter_component cc_type = native_bt.COMPONENT_CLASS_TYPE_FILTER elif isinstance(component_class, bt2_component._SinkComponentClass): cc_ptr = component_class._ptr - add_fn = native_bt.graph_add_sink_component + add_fn = native_bt.bt2_graph_add_sink_component cc_type = native_bt.COMPONENT_CLASS_TYPE_SINK elif issubclass(component_class, bt2_component._UserSourceComponent): cc_ptr = component_class._bt_cc_ptr - add_fn = native_bt.graph_add_source_component + add_fn = native_bt.bt2_graph_add_source_component cc_type = native_bt.COMPONENT_CLASS_TYPE_SOURCE elif issubclass(component_class, bt2_component._UserSinkComponent): cc_ptr = component_class._bt_cc_ptr - add_fn = native_bt.graph_add_sink_component + add_fn = native_bt.bt2_graph_add_sink_component cc_type = native_bt.COMPONENT_CLASS_TYPE_SINK elif issubclass(component_class, bt2_component._UserFilterComponent): cc_ptr = component_class._bt_cc_ptr - add_fn = native_bt.graph_add_filter_component + add_fn = native_bt.bt2_graph_add_filter_component cc_type = native_bt.COMPONENT_CLASS_TYPE_FILTER else: raise TypeError( @@ -119,11 +120,17 @@ class Graph(object._SharedObject): utils._check_str(name) utils._check_log_level(logging_level) - params = bt2.create_value(params) + base_cc_ptr = component_class._bt_component_class_ptr() + + if obj is not None and not native_bt.bt2_is_python_component_class(base_cc_ptr): + raise ValueError('cannot pass a Python object to a non-Python component') + params = bt2.create_value(params) params_ptr = params._ptr if params is not None else None - status, comp_ptr = add_fn(self._ptr, cc_ptr, name, params_ptr, logging_level) + status, comp_ptr = add_fn( + self._ptr, cc_ptr, name, params_ptr, obj, logging_level + ) utils._handle_func_status(status, 'cannot add component to graph') assert comp_ptr return bt2_component._create_component_from_ptr(comp_ptr, cc_type) diff --git a/src/bindings/python/bt2/bt2/native_bt_component_class.i b/src/bindings/python/bt2/bt2/native_bt_component_class.i index 8efe8147..4c26660f 100644 --- a/src/bindings/python/bt2/bt2/native_bt_component_class.i +++ b/src/bindings/python/bt2/bt2/native_bt_component_class.i @@ -48,3 +48,4 @@ struct bt_component_class_sink *bt_bt2_component_class_sink_create( PyObject *py_cls, const char *name, const char *description, const char *help); void bt_bt2_unregister_cc_ptr_to_py_cls(const bt_component_class *comp_cls); +bool bt_bt2_is_python_component_class(const bt_component_class *comp_cls); diff --git a/src/bindings/python/bt2/bt2/native_bt_component_class.i.h b/src/bindings/python/bt2/bt2/native_bt_component_class.i.h index fc10efef..9b1e7d27 100644 --- a/src/bindings/python/bt2/bt2/native_bt_component_class.i.h +++ b/src/bindings/python/bt2/bt2/native_bt_component_class.i.h @@ -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: " diff --git a/src/bindings/python/bt2/bt2/native_bt_graph.i b/src/bindings/python/bt2/bt2/native_bt_graph.i index ccb3c246..a2e623e5 100644 --- a/src/bindings/python/bt2/bt2/native_bt_graph.i +++ b/src/bindings/python/bt2/bt2/native_bt_graph.i @@ -112,5 +112,30 @@ PyObject *bt_bt2_graph_add_port_added_listener(struct bt_graph *graph, PyObject *py_callable); + PyObject *bt_bt2_graph_add_ports_connected_listener(struct bt_graph *graph, PyObject *py_callable); + +bt_graph_add_component_status +bt_bt2_graph_add_source_component( + bt_graph *graph, + const bt_component_class_source *component_class, + const char *name, const bt_value *params, + PyObject *obj, bt_logging_level log_level, + const bt_component_source **component); + +bt_graph_add_component_status +bt_bt2_graph_add_filter_component( + bt_graph *graph, + const bt_component_class_filter *component_class, + const char *name, const bt_value *params, + PyObject *obj, bt_logging_level log_level, + const bt_component_filter **component); + +bt_graph_add_component_status +bt_bt2_graph_add_sink_component( + bt_graph *graph, + const bt_component_class_sink *component_class, + const char *name, const bt_value *params, + PyObject *obj, bt_logging_level log_level, + const bt_component_sink **component); diff --git a/src/bindings/python/bt2/bt2/native_bt_graph.i.h b/src/bindings/python/bt2/bt2/native_bt_graph.i.h index bccc1825..a7193497 100644 --- a/src/bindings/python/bt2/bt2/native_bt_graph.i.h +++ b/src/bindings/python/bt2/bt2/native_bt_graph.i.h @@ -513,3 +513,45 @@ end: Py_XDECREF(py_listener_id); return py_listener_ids; } + +static +bt_graph_add_component_status +bt_bt2_graph_add_source_component( + bt_graph *graph, + const bt_component_class_source *component_class, + const char *name, const bt_value *params, + PyObject *obj, bt_logging_level log_level, + const bt_component_source **component) +{ + return bt_graph_add_source_component_with_init_method_data(graph, + component_class, name, params, obj == Py_None ? NULL : obj, + log_level, component); +} + +static +bt_graph_add_component_status +bt_bt2_graph_add_filter_component( + bt_graph *graph, + const bt_component_class_filter *component_class, + const char *name, const bt_value *params, + PyObject *obj, bt_logging_level log_level, + const bt_component_filter **component) +{ + return bt_graph_add_filter_component_with_init_method_data(graph, + component_class, name, params, obj == Py_None ? NULL : obj, + log_level, component); +} + +static +bt_graph_add_component_status +bt_bt2_graph_add_sink_component( + bt_graph *graph, + const bt_component_class_sink *component_class, + const char *name, const bt_value *params, + PyObject *obj, bt_logging_level log_level, + const bt_component_sink **component) +{ + return bt_graph_add_sink_component_with_init_method_data(graph, + component_class, name, params, obj == Py_None ? NULL : obj, + log_level, component); +} diff --git a/src/bindings/python/bt2/bt2/trace_collection_message_iterator.py b/src/bindings/python/bt2/bt2/trace_collection_message_iterator.py index fd579068..4e7361e7 100644 --- a/src/bindings/python/bt2/bt2/trace_collection_message_iterator.py +++ b/src/bindings/python/bt2/bt2/trace_collection_message_iterator.py @@ -41,6 +41,7 @@ class ComponentSpec: plugin_name, class_name, params=None, + obj=None, logging_level=bt2_logging.LoggingLevel.NONE, ): utils._check_str(plugin_name) @@ -49,6 +50,7 @@ class ComponentSpec: self._plugin_name = plugin_name self._class_name = class_name self._logging_level = logging_level + self._obj = obj if type(params) is str: self._params = bt2.create_value({'inputs': [params]}) @@ -71,6 +73,10 @@ class ComponentSpec: def params(self): return self._params + @property + def obj(self): + return self._obj + # datetime.datetime or integral to nanoseconds def _get_ns(obj): @@ -262,7 +268,7 @@ class TraceCollectionMessageIterator(bt2_message_iterator._MessageIterator): comp_cls = comp_classes[comp_spec.class_name] name = self._get_unique_comp_name(comp_spec) comp = self._graph.add_component( - comp_cls, name, comp_spec.params, comp_spec.logging_level + comp_cls, name, comp_spec.params, comp_spec.obj, comp_spec.logging_level ) return comp diff --git a/tests/bindings/python/bt2/test_clock_class.py b/tests/bindings/python/bt2/test_clock_class.py index d41b4671..48ae9602 100644 --- a/tests/bindings/python/bt2/test_clock_class.py +++ b/tests/bindings/python/bt2/test_clock_class.py @@ -239,7 +239,7 @@ class ClockSnapshotTestCase(unittest.TestCase): return notif class MySrc(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(self, params): + def __init__(self, params, obj): self._add_output_port('out') self._graph = bt2.Graph() diff --git a/tests/bindings/python/bt2/test_component.py b/tests/bindings/python/bt2/test_component.py index e347d981..d420f926 100644 --- a/tests/bindings/python/bt2/test_component.py +++ b/tests/bindings/python/bt2/test_component.py @@ -33,7 +33,7 @@ class UserComponentTestCase(unittest.TestCase): def test_name(self): class MySink(bt2._UserSinkComponent): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): self.assertEqual(comp_self.name, 'yaes') def _user_consume(self): @@ -43,7 +43,7 @@ class UserComponentTestCase(unittest.TestCase): def test_logging_level(self): class MySink(bt2._UserSinkComponent): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): self.assertEqual(comp_self.logging_level, bt2.LoggingLevel.INFO) def _user_consume(self): @@ -53,7 +53,7 @@ class UserComponentTestCase(unittest.TestCase): def test_class(self): class MySink(bt2._UserSinkComponent): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): self.assertEqual(comp_self.cls, MySink) def _user_consume(self): @@ -63,7 +63,7 @@ class UserComponentTestCase(unittest.TestCase): def test_addr(self): class MySink(bt2._UserSinkComponent): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): self.assertIsInstance(comp_self.addr, int) self.assertNotEqual(comp_self.addr, 0) diff --git a/tests/bindings/python/bt2/test_connection.py b/tests/bindings/python/bt2/test_connection.py index 898c6871..131e1d75 100644 --- a/tests/bindings/python/bt2/test_connection.py +++ b/tests/bindings/python/bt2/test_connection.py @@ -27,11 +27,11 @@ class ConnectionTestCase(unittest.TestCase): raise bt2.Stop class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(self, params): + def __init__(self, params, obj): self._add_output_port('out') class MySink(bt2._UserSinkComponent): - def __init__(self, params): + def __init__(self, params, obj): self._add_input_port('in') def _user_consume(self): @@ -48,11 +48,11 @@ class ConnectionTestCase(unittest.TestCase): raise bt2.Stop class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(self, params): + def __init__(self, params, obj): self._add_output_port('out') class MySink(bt2._UserSinkComponent): - def __init__(self, params): + def __init__(self, params, obj): self._add_input_port('in') def _user_consume(self): @@ -70,11 +70,11 @@ class ConnectionTestCase(unittest.TestCase): raise bt2.Stop class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(self, params): + def __init__(self, params, obj): self._add_output_port('out') class MySink(bt2._UserSinkComponent): - def __init__(self, params): + def __init__(self, params, obj): self._add_input_port('in') def _user_consume(self): diff --git a/tests/bindings/python/bt2/test_error.py b/tests/bindings/python/bt2/test_error.py index b09dded2..9c2a9e52 100644 --- a/tests/bindings/python/bt2/test_error.py +++ b/tests/bindings/python/bt2/test_error.py @@ -29,19 +29,19 @@ class FailingIter(bt2._UserMessageIterator): class SourceWithFailingIter( bt2._UserSourceComponent, message_iterator_class=FailingIter ): - def __init__(self, params): + def __init__(self, params, obj): self._add_output_port('out') class SourceWithFailingInit( bt2._UserSourceComponent, message_iterator_class=FailingIter ): - def __init__(self, params): + def __init__(self, params, obj): raise ValueError('Source is failing') class WorkingSink(bt2._UserSinkComponent): - def __init__(self, params): + def __init__(self, params, obj): self._in = self._add_input_port('in') def _user_graph_is_configured(self): @@ -52,7 +52,7 @@ class WorkingSink(bt2._UserSinkComponent): class SinkWithExceptionChaining(bt2._UserSinkComponent): - def __init__(self, params): + def __init__(self, params, obj): self._in = self._add_input_port('in') def _user_graph_is_configured(self): diff --git a/tests/bindings/python/bt2/test_event.py b/tests/bindings/python/bt2/test_event.py index ab65e0fa..ea65b590 100644 --- a/tests/bindings/python/bt2/test_event.py +++ b/tests/bindings/python/bt2/test_event.py @@ -75,7 +75,7 @@ class EventTestCase(unittest.TestCase): return msg class MySrc(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(self, params): + def __init__(self, params, obj): self._add_output_port('out') tc = self._create_trace_class() diff --git a/tests/bindings/python/bt2/test_graph.py b/tests/bindings/python/bt2/test_graph.py index bda08de2..b7c0f0cb 100644 --- a/tests/bindings/python/bt2/test_graph.py +++ b/tests/bindings/python/bt2/test_graph.py @@ -79,7 +79,7 @@ class GraphTestCase(unittest.TestCase): comp_params = None class MySink(bt2._UserSinkComponent): - def __init__(self, params): + def __init__(self, params, obj): nonlocal comp_params comp_params = params @@ -91,6 +91,48 @@ class GraphTestCase(unittest.TestCase): self.assertEqual(params, comp_params) del comp_params + def test_add_component_obj_python_comp_cls(self): + comp_obj = None + + class MySink(bt2._UserSinkComponent): + def __init__(self, params, obj): + nonlocal comp_obj + comp_obj = obj + + def _user_consume(self): + pass + + obj = object() + comp = self._graph.add_component(MySink, 'salut', obj=obj) + self.assertIs(comp_obj, obj) + del comp_obj + + def test_add_component_obj_none_python_comp_cls(self): + comp_obj = None + + class MySink(bt2._UserSinkComponent): + def __init__(self, params, obj): + nonlocal comp_obj + comp_obj = obj + + def _user_consume(self): + pass + + comp = self._graph.add_component(MySink, 'salut') + self.assertIsNone(comp_obj) + del comp_obj + + def test_add_component_obj_non_python_comp_cls(self): + comp_obj = None + + plugin = bt2.find_plugin('text', find_in_user_dir=False, find_in_sys_dir=False) + assert plugin is not None + cc = plugin.source_component_classes['dmesg'] + assert cc is not None + + with self.assertRaises(ValueError): + comp = self._graph.add_component(cc, 'salut', obj=57) + def test_add_component_invalid_cls_type(self): with self.assertRaises(TypeError): self._graph.add_component(int, 'salut') @@ -127,11 +169,11 @@ class GraphTestCase(unittest.TestCase): raise bt2.Stop class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(self, params): + def __init__(self, params, obj): self._add_output_port('out') class MySink(bt2._UserSinkComponent): - def __init__(self, params): + def __init__(self, params, obj): self._add_input_port('in') def _user_consume(self): @@ -154,11 +196,11 @@ class GraphTestCase(unittest.TestCase): raise bt2.Stop class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(self, params): + def __init__(self, params, obj): self._add_output_port('out') class MySink(bt2._UserSinkComponent): - def __init__(self, params): + def __init__(self, params, obj): self._add_input_port('in') def _user_consume(self): @@ -178,11 +220,11 @@ class GraphTestCase(unittest.TestCase): raise TypeError class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(self, params): + def __init__(self, params, obj): self._add_output_port('out') class MySink(bt2._UserSinkComponent): - def __init__(self, params): + def __init__(self, params, obj): self._add_input_port('in') def _user_consume(self): @@ -223,11 +265,11 @@ class GraphTestCase(unittest.TestCase): return self._create_stream_beginning_message(self._stream) class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(self, params): + def __init__(self, params, obj): self._add_output_port('out') class MySink(bt2._UserSinkComponent): - def __init__(self, params): + def __init__(self, params, obj): self._add_input_port('in') def _user_consume(self): @@ -270,11 +312,11 @@ class GraphTestCase(unittest.TestCase): return msg class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(self, params): + def __init__(self, params, obj): self._add_output_port('out') class MySink(bt2._UserSinkComponent): - def __init__(self, params): + def __init__(self, params, obj): self._input_port = self._add_input_port('in') self._at = 0 @@ -324,11 +366,11 @@ class GraphTestCase(unittest.TestCase): return msg class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(self, params): + def __init__(self, params, obj): self._add_output_port('out') class MySink(bt2._UserSinkComponent): - def __init__(self, params): + def __init__(self, params, obj): self._input_port = self._add_input_port('in') self._at = 0 @@ -382,11 +424,11 @@ class GraphTestCase(unittest.TestCase): return msg class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(self, params): + def __init__(self, params, obj): self._add_output_port('out') class MySink(bt2._UserSinkComponent): - def __init__(self, params): + def __init__(self, params, obj): self._input_port = self._add_input_port('in') self._at = 0 @@ -425,12 +467,12 @@ class GraphTestCase(unittest.TestCase): raise bt2.Stop class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(self, params): + def __init__(self, params, obj): self._add_output_port('out') self._add_output_port('zero') class MySink(bt2._UserSinkComponent): - def __init__(self, params): + def __init__(self, params, obj): self._add_input_port('in') def _user_consume(self): @@ -494,12 +536,12 @@ class GraphTestCase(unittest.TestCase): raise bt2.Stop class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(self, params): + def __init__(self, params, obj): self._add_output_port('out') self._add_output_port('zero') class MySink(bt2._UserSinkComponent): - def __init__(self, params): + def __init__(self, params, obj): self._add_input_port('in') def _user_consume(self): @@ -515,7 +557,7 @@ class GraphTestCase(unittest.TestCase): def test_raise_in_component_init(self): class MySink(bt2._UserSinkComponent): - def __init__(self, params): + def __init__(self, params, obj): raise ValueError('oops!') def _user_consume(self): @@ -528,7 +570,7 @@ class GraphTestCase(unittest.TestCase): def test_raise_in_port_added_listener(self): class MySink(bt2._UserSinkComponent): - def __init__(self, params): + def __init__(self, params, obj): self._add_input_port('in') def _user_consume(self): @@ -549,11 +591,11 @@ class GraphTestCase(unittest.TestCase): raise bt2.Stop class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(self, params): + def __init__(self, params, obj): self._add_output_port('out') class MySink(bt2._UserSinkComponent): - def __init__(self, params): + def __init__(self, params, obj): self._add_input_port('in') def _user_consume(self): diff --git a/tests/bindings/python/bt2/test_message.py b/tests/bindings/python/bt2/test_message.py index da91b753..78e8dec0 100644 --- a/tests/bindings/python/bt2/test_message.py +++ b/tests/bindings/python/bt2/test_message.py @@ -102,7 +102,7 @@ class AllMessagesTestCase(unittest.TestCase): return msg class MySrc(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(self, params): + def __init__(self, params, obj): self._add_output_port('out', params) with_cc = bool(params['with_cc']) diff --git a/tests/bindings/python/bt2/test_message_iterator.py b/tests/bindings/python/bt2/test_message_iterator.py index 08be7d00..43af1e1f 100644 --- a/tests/bindings/python/bt2/test_message_iterator.py +++ b/tests/bindings/python/bt2/test_message_iterator.py @@ -27,7 +27,7 @@ class UserMessageIteratorTestCase(unittest.TestCase): @staticmethod def _create_graph(src_comp_cls, flt_comp_cls=None): class MySink(bt2._UserSinkComponent): - def __init__(self, params): + def __init__(self, params, obj): self._add_input_port('in') def _user_consume(self): @@ -70,7 +70,7 @@ class UserMessageIteratorTestCase(unittest.TestCase): the_output_port_from_iter = self_port_output class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(self, params): + def __init__(self, params, obj): nonlocal the_output_port_from_source the_output_port_from_source = self._add_output_port('out', 'user data') @@ -90,7 +90,7 @@ class UserMessageIteratorTestCase(unittest.TestCase): src_iter_initialized = True class MySource(bt2._UserSourceComponent, message_iterator_class=MySourceIter): - def __init__(self, params): + def __init__(self, params, obj): self._add_output_port('out') class MyFilterIter(bt2._UserMessageIterator): @@ -105,7 +105,7 @@ class UserMessageIteratorTestCase(unittest.TestCase): return next(self._up_iter) class MyFilter(bt2._UserFilterComponent, message_iterator_class=MyFilterIter): - def __init__(self, params): + def __init__(self, params, obj): self._add_input_port('in') self._add_output_port('out') @@ -123,7 +123,7 @@ class UserMessageIteratorTestCase(unittest.TestCase): finalized = True class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(self, params): + def __init__(self, params, obj): self._add_output_port('out') finalized = False @@ -139,7 +139,7 @@ class UserMessageIteratorTestCase(unittest.TestCase): salut = self._component._salut class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(self, params): + def __init__(self, params, obj): self._add_output_port('out') self._salut = 23 @@ -155,7 +155,7 @@ class UserMessageIteratorTestCase(unittest.TestCase): addr = self.addr class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(self, params): + def __init__(self, params, obj): self._add_output_port('out') addr = None @@ -188,7 +188,7 @@ class UserMessageIteratorTestCase(unittest.TestCase): return self._msgs.pop(0) class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(self, params): + def __init__(self, params, obj): tc = self._create_trace_class() sc = tc.create_stream_class(supports_packets=True) ec = sc.create_event_class() @@ -247,7 +247,7 @@ class UserMessageIteratorTestCase(unittest.TestCase): raise StopIteration class MySource(bt2._UserSourceComponent, message_iterator_class=MySourceIter): - def __init__(self, params): + def __init__(self, params, obj): tc = self._create_trace_class() sc = tc.create_stream_class(supports_packets=True) ec = sc.create_event_class() @@ -272,7 +272,7 @@ class UserMessageIteratorTestCase(unittest.TestCase): return self._upstream_iter.can_seek_beginning class MyFilter(bt2._UserFilterComponent, message_iterator_class=MyFilterIter): - def __init__(self, params): + def __init__(self, params, obj): input_port = self._add_input_port('in') self._add_output_port('out', input_port) @@ -360,7 +360,7 @@ class UserMessageIteratorTestCase(unittest.TestCase): raise bt2.TryAgain class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(self, params): + def __init__(self, params, obj): self._add_output_port('out') graph = bt2.Graph() @@ -403,7 +403,7 @@ class OutputPortMessageIteratorTestCase(unittest.TestCase): return msg class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(self, params): + def __init__(self, params, obj): self._add_output_port('out') trace_class = self._create_trace_class() diff --git a/tests/bindings/python/bt2/test_port.py b/tests/bindings/python/bt2/test_port.py index 8be3f38c..7e489d32 100644 --- a/tests/bindings/python/bt2/test_port.py +++ b/tests/bindings/python/bt2/test_port.py @@ -36,7 +36,7 @@ class PortTestCase(unittest.TestCase): raise bt2.Stop class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): port = comp_self._add_output_port('out') self.assertEqual(port.name, 'out') @@ -49,7 +49,7 @@ class PortTestCase(unittest.TestCase): raise bt2.Stop class MyFilter(bt2._UserFilterComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): port = comp_self._add_output_port('out') self.assertEqual(port.name, 'out') @@ -62,7 +62,7 @@ class PortTestCase(unittest.TestCase): raise bt2.Stop class MyFilter(bt2._UserFilterComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): port = comp_self._add_input_port('in') self.assertEqual(port.name, 'in') @@ -71,7 +71,7 @@ class PortTestCase(unittest.TestCase): def test_sink_add_input_port(self): class MySink(bt2._UserSinkComponent): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): port = comp_self._add_input_port('in') self.assertEqual(port.name, 'in') @@ -87,7 +87,7 @@ class PortTestCase(unittest.TestCase): raise bt2.Stop class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): port1 = comp_self._add_output_port('clear') port2 = comp_self._add_output_port('print') port3 = comp_self._add_output_port('insert') @@ -103,7 +103,7 @@ class PortTestCase(unittest.TestCase): raise bt2.Stop class MyFilter(bt2._UserFilterComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): port1 = comp_self._add_output_port('clear') port2 = comp_self._add_output_port('print') port3 = comp_self._add_output_port('insert') @@ -119,7 +119,7 @@ class PortTestCase(unittest.TestCase): raise bt2.Stop class MyFilter(bt2._UserFilterComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): port1 = comp_self._add_input_port('clear') port2 = comp_self._add_input_port('print') port3 = comp_self._add_input_port('insert') @@ -131,7 +131,7 @@ class PortTestCase(unittest.TestCase): def test_user_sink_input_ports_getitem(self): class MySink(bt2._UserSinkComponent): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): port1 = comp_self._add_input_port('clear') port2 = comp_self._add_input_port('print') port3 = comp_self._add_input_port('insert') @@ -150,7 +150,7 @@ class PortTestCase(unittest.TestCase): raise bt2.Stop class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): comp_self._add_output_port('clear') comp_self._add_output_port('print') comp_self._add_output_port('insert') @@ -166,7 +166,7 @@ class PortTestCase(unittest.TestCase): raise bt2.Stop class MyFilter(bt2._UserFilterComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): comp_self._add_output_port('clear') comp_self._add_output_port('print') comp_self._add_output_port('insert') @@ -182,7 +182,7 @@ class PortTestCase(unittest.TestCase): raise bt2.Stop class MyFilter(bt2._UserFilterComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): comp_self._add_input_port('clear') comp_self._add_input_port('print') comp_self._add_input_port('insert') @@ -194,7 +194,7 @@ class PortTestCase(unittest.TestCase): def test_user_sink_input_ports_getitem_invalid_key(self): class MySink(bt2._UserSinkComponent): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): comp_self._add_input_port('clear') comp_self._add_input_port('print') comp_self._add_input_port('insert') @@ -213,7 +213,7 @@ class PortTestCase(unittest.TestCase): raise bt2.Stop class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): comp_self._add_output_port('clear') comp_self._add_output_port('print') comp_self._add_output_port('insert') @@ -227,7 +227,7 @@ class PortTestCase(unittest.TestCase): raise bt2.Stop class MyFilter(bt2._UserFilterComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): comp_self._add_output_port('clear') comp_self._add_output_port('print') comp_self._add_output_port('insert') @@ -241,7 +241,7 @@ class PortTestCase(unittest.TestCase): raise bt2.Stop class MyFilter(bt2._UserFilterComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): comp_self._add_input_port('clear') comp_self._add_input_port('print') comp_self._add_input_port('insert') @@ -251,7 +251,7 @@ class PortTestCase(unittest.TestCase): def test_user_sink_input_ports_len(self): class MySink(bt2._UserSinkComponent): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): comp_self._add_input_port('clear') comp_self._add_input_port('print') comp_self._add_input_port('insert') @@ -268,7 +268,7 @@ class PortTestCase(unittest.TestCase): raise bt2.Stop class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): port1 = comp_self._add_output_port('clear') port2 = comp_self._add_output_port('print') port3 = comp_self._add_output_port('insert') @@ -292,7 +292,7 @@ class PortTestCase(unittest.TestCase): raise bt2.Stop class MyFilter(bt2._UserFilterComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): port1 = comp_self._add_output_port('clear') port2 = comp_self._add_output_port('print') port3 = comp_self._add_output_port('insert') @@ -316,7 +316,7 @@ class PortTestCase(unittest.TestCase): raise bt2.Stop class MyFilter(bt2._UserFilterComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): port1 = comp_self._add_input_port('clear') port2 = comp_self._add_input_port('print') port3 = comp_self._add_input_port('insert') @@ -336,7 +336,7 @@ class PortTestCase(unittest.TestCase): def test_user_sink_input_ports_iter(self): class MySink(bt2._UserSinkComponent): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): port1 = comp_self._add_input_port('clear') port2 = comp_self._add_input_port('print') port3 = comp_self._add_input_port('insert') @@ -367,7 +367,7 @@ class PortTestCase(unittest.TestCase): port3 = None class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): nonlocal port1, port2, port3 port1 = comp_self._add_output_port('clear') port2 = comp_self._add_output_port('print') @@ -391,7 +391,7 @@ class PortTestCase(unittest.TestCase): port3 = None class MyFilter(bt2._UserFilterComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): nonlocal port1, port2, port3 port1 = comp_self._add_output_port('clear') port2 = comp_self._add_output_port('print') @@ -415,7 +415,7 @@ class PortTestCase(unittest.TestCase): port3 = None class MyFilter(bt2._UserFilterComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): nonlocal port1, port2, port3 port1 = comp_self._add_input_port('clear') port2 = comp_self._add_input_port('print') @@ -435,7 +435,7 @@ class PortTestCase(unittest.TestCase): port3 = None class MySink(bt2._UserSinkComponent): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): nonlocal port1, port2, port3 port1 = comp_self._add_input_port('clear') port2 = comp_self._add_input_port('print') @@ -458,7 +458,7 @@ class PortTestCase(unittest.TestCase): raise bt2.Stop class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): comp_self._add_output_port('clear') comp_self._add_output_port('print') comp_self._add_output_port('insert') @@ -474,7 +474,7 @@ class PortTestCase(unittest.TestCase): raise bt2.Stop class MyFilter(bt2._UserFilterComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): comp_self._add_output_port('clear') comp_self._add_output_port('print') comp_self._add_output_port('insert') @@ -490,7 +490,7 @@ class PortTestCase(unittest.TestCase): raise bt2.Stop class MyFilter(bt2._UserFilterComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): comp_self._add_input_port('clear') comp_self._add_input_port('print') comp_self._add_input_port('insert') @@ -502,7 +502,7 @@ class PortTestCase(unittest.TestCase): def test_gen_sink_input_ports_getitem_invalid_key(self): class MySink(bt2._UserSinkComponent): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): comp_self._add_input_port('clear') comp_self._add_input_port('print') comp_self._add_input_port('insert') @@ -524,7 +524,7 @@ class PortTestCase(unittest.TestCase): raise bt2.Stop class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): comp_self._add_output_port('clear') comp_self._add_output_port('print') comp_self._add_output_port('insert') @@ -538,7 +538,7 @@ class PortTestCase(unittest.TestCase): raise bt2.Stop class MyFilter(bt2._UserFilterComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): comp_self._add_output_port('clear') comp_self._add_output_port('print') comp_self._add_output_port('insert') @@ -552,7 +552,7 @@ class PortTestCase(unittest.TestCase): raise bt2.Stop class MyFilter(bt2._UserFilterComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): comp_self._add_input_port('clear') comp_self._add_input_port('print') comp_self._add_input_port('insert') @@ -562,7 +562,7 @@ class PortTestCase(unittest.TestCase): def test_gen_sink_input_ports_len(self): class MySink(bt2._UserSinkComponent): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): comp_self._add_input_port('clear') comp_self._add_input_port('print') comp_self._add_input_port('insert') @@ -583,7 +583,7 @@ class PortTestCase(unittest.TestCase): port3 = None class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): nonlocal port1, port2, port3 port1 = comp_self._add_output_port('clear') port2 = comp_self._add_output_port('print') @@ -615,7 +615,7 @@ class PortTestCase(unittest.TestCase): port3 = None class MyFilter(bt2._UserFilterComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): nonlocal port1, port2, port3 port1 = comp_self._add_output_port('clear') port2 = comp_self._add_output_port('print') @@ -647,7 +647,7 @@ class PortTestCase(unittest.TestCase): port3 = None class MyFilter(bt2._UserFilterComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): nonlocal port1, port2, port3 port1 = comp_self._add_input_port('clear') port2 = comp_self._add_input_port('print') @@ -675,7 +675,7 @@ class PortTestCase(unittest.TestCase): port3 = None class MySink(bt2._UserSinkComponent): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): nonlocal port1, port2, port3 port1 = comp_self._add_input_port('clear') port2 = comp_self._add_input_port('print') @@ -702,7 +702,7 @@ class PortTestCase(unittest.TestCase): def test_name(self): class MySink(bt2._UserSinkComponent): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): comp_self._add_input_port('clear') def _user_consume(self): @@ -713,7 +713,7 @@ class PortTestCase(unittest.TestCase): def test_connection_none(self): class MySink(bt2._UserSinkComponent): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): comp_self._add_input_port('clear') def _user_consume(self): @@ -724,7 +724,7 @@ class PortTestCase(unittest.TestCase): def test_is_connected_false(self): class MySink(bt2._UserSinkComponent): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): comp_self._add_input_port('clear') def _user_consume(self): @@ -735,7 +735,7 @@ class PortTestCase(unittest.TestCase): def test_self_name(self): class MySink(bt2._UserSinkComponent): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): port = comp_self._add_input_port('clear') self.assertEqual(port.name, 'clear') @@ -746,7 +746,7 @@ class PortTestCase(unittest.TestCase): def test_self_connection_none(self): class MySink(bt2._UserSinkComponent): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): port = comp_self._add_input_port('clear') self.assertIsNone(port.connection) @@ -757,7 +757,7 @@ class PortTestCase(unittest.TestCase): def test_self_is_connected_false(self): class MySink(bt2._UserSinkComponent): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): port = comp_self._add_input_port('clear') self.assertFalse(port.is_connected) @@ -772,7 +772,7 @@ class PortTestCase(unittest.TestCase): raise bt2.Stop class MySource(bt2._UserFilterComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): nonlocal user_datas p = comp_self._add_output_port('port1') @@ -791,7 +791,7 @@ class PortTestCase(unittest.TestCase): raise bt2.Stop class MyFilter(bt2._UserFilterComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): nonlocal user_datas p = comp_self._add_output_port('port1') @@ -817,7 +817,7 @@ class PortTestCase(unittest.TestCase): raise bt2.Stop class MySink(bt2._UserFilterComponent, message_iterator_class=MyIter): - def __init__(comp_self, params): + def __init__(comp_self, params, obj): nonlocal user_datas p = comp_self._add_input_port('port1') diff --git a/tests/bindings/python/bt2/utils.py b/tests/bindings/python/bt2/utils.py index 46be6fe2..1f9a6c27 100644 --- a/tests/bindings/python/bt2/utils.py +++ b/tests/bindings/python/bt2/utils.py @@ -26,7 +26,7 @@ import bt2 def run_in_component_init(func): class MySink(bt2._UserSinkComponent): - def __init__(self, params): + def __init__(self, params, obj): nonlocal res_bound res_bound = func(self) diff --git a/tests/data/cli/convert/auto-source-discovery-grouping/bt_plugin_test.py b/tests/data/cli/convert/auto-source-discovery-grouping/bt_plugin_test.py index 4d6e86e2..3719ceb9 100644 --- a/tests/data/cli/convert/auto-source-discovery-grouping/bt_plugin_test.py +++ b/tests/data/cli/convert/auto-source-discovery-grouping/bt_plugin_test.py @@ -22,7 +22,7 @@ class TestSourceExt(Base, bt2._UserSourceComponent, message_iterator_class=TestI files are not grouped. """ - def __init__(self, params): + def __init__(self, params, obj): self._print_params(params) @staticmethod @@ -60,7 +60,7 @@ class TestSourceSomeDir( directory "some-dir" won't be found by TestSourceExt, because we won't recurse in "some-dir".""" - def __init__(self, params): + def __init__(self, params, obj): self._print_params(params) @staticmethod @@ -79,7 +79,7 @@ class TestSourceSomeDir( class TestSourceABCDE(Base, bt2._UserSourceComponent, message_iterator_class=TestIter): """A source that recognizes the arbitrary string input "ABCDE".""" - def __init__(self, params): + def __init__(self, params, obj): self._print_params(params) @staticmethod diff --git a/tests/data/plugins/flt.utils.trimmer/bt_plugin_trimmer_test.py b/tests/data/plugins/flt.utils.trimmer/bt_plugin_trimmer_test.py index 69abd1aa..c7d5985d 100644 --- a/tests/data/plugins/flt.utils.trimmer/bt_plugin_trimmer_test.py +++ b/tests/data/plugins/flt.utils.trimmer/bt_plugin_trimmer_test.py @@ -49,7 +49,7 @@ class TheIteratorOfAllEvil(bt2._UserMessageIterator): class TheSourceOfAllEvil( bt2._UserSourceComponent, message_iterator_class=TheIteratorOfAllEvil ): - def __init__(self, params): + def __init__(self, params, obj): tc = self._create_trace_class() # Use a clock class with an offset, so we can test with --begin or --end -- 2.34.1