From 2f16a6a228d0059349b8566979c9d579e7e271b3 Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Fri, 31 May 2019 07:56:44 -0400 Subject: [PATCH] bt2: always use staticmethod() with native function class attributes This is a recurrent pattern in the Python bindings: class Something(_SomeBase): _set_value = native_bt.something_set_value Then template methods in `_SomeBase` can use this class attribute by name within the template. This function needs to be a static method, because template methods do: self._set_value(...) and native_bt.something_set_value() must not receive `self` as its first argument. For some reason, when you set a class attribute to a native function (defined within an extension module), it is automatically a static method, so you don't need to specify it manually. It is not the case for any other Python function. With SWIG 3, the generated wrapper code in `native_bt.py` looks like: def value_unsigned_integer_set(integer_obj, val): return _native_bt.value_unsigned_integer_set(integer_obj, val) value_unsigned_integer_set = _native_bt.value_unsigned_integer_set There's a defined Python function, but then the same name is reassigned to the native function itself (`_native_bt.value_unsigned_integer_set`). I didn't investigate why SWIG does that; it could be an optimization, but then I don't get why the Python wrapper is created in the first place. This means that, with: class UnsignedIntegerValue(_IntegerValue): ... _set_value = native_bt.value_unsigned_integer_set ... UnsignedIntegerValue._set_value() is a static method. However, with SWIG 4, the generated wrapper looks like this: def value_unsigned_integer_set(integer_obj, val): return _native_bt.value_unsigned_integer_set(integer_obj, val) For some reason, the value_unsigned_integer_set = _native_bt.value_unsigned_integer_set part is gone. Now, UnsignedIntegerValue._set_value() is not a static method anymore, so calling it with `self._set_value()` gives the expected: TypeError: value_unsigned_integer_set() takes 2 positional arguments but 3 were given Instead of trying to make SWIG 4 generate this native function assignment again, I prefer to be more explicit/clean and use staticmethod() to force the function into a static method. From https://docs.python.org/3/library/functions.html#staticmethod, the documentation also suggests this: > Like all decorators, it is also possible to call staticmethod as a > regular function and do something with its result. This is needed in > some cases where you need a reference to a function from a class body > and you want to avoid the automatic transformation to instance method. > For these cases, use this idiom: > > class C: > builtin_open = staticmethod(open) Signed-off-by: Philippe Proulx Change-Id: Ic51397e34132adc78fddc3105878080a8bf74ff9 Reviewed-on: https://review.lttng.org/c/babeltrace/+/1357 Tested-by: jenkins Reviewed-by: Simon Marchi --- bindings/python/bt2/bt2/component.py | 46 +++++++++++------------ bindings/python/bt2/bt2/graph.py | 4 +- bindings/python/bt2/bt2/plugin.py | 26 ++++++------- bindings/python/bt2/bt2/query_executor.py | 4 +- bindings/python/bt2/bt2/value.py | 20 +++++----- 5 files changed, 50 insertions(+), 50 deletions(-) diff --git a/bindings/python/bt2/bt2/component.py b/bindings/python/bt2/bt2/component.py index 8e07da32..3c820cba 100644 --- a/bindings/python/bt2/bt2/component.py +++ b/bindings/python/bt2/bt2/component.py @@ -78,21 +78,21 @@ class _GenericComponentClass(object._SharedObject): class _GenericSourceComponentClass(_GenericComponentClass): - _get_ref = native_bt.component_class_source_get_ref - _put_ref = native_bt.component_class_source_put_ref - _as_component_class_ptr = native_bt.component_class_source_as_component_class + _get_ref = staticmethod(native_bt.component_class_source_get_ref) + _put_ref = staticmethod(native_bt.component_class_source_put_ref) + _as_component_class_ptr = staticmethod(native_bt.component_class_source_as_component_class) class _GenericFilterComponentClass(_GenericComponentClass): - _get_ref = native_bt.component_class_filter_get_ref - _put_ref = native_bt.component_class_filter_put_ref - _as_component_class_ptr = native_bt.component_class_filter_as_component_class + _get_ref = staticmethod(native_bt.component_class_filter_get_ref) + _put_ref = staticmethod(native_bt.component_class_filter_put_ref) + _as_component_class_ptr = staticmethod(native_bt.component_class_filter_as_component_class) class _GenericSinkComponentClass(_GenericComponentClass): - _get_ref = native_bt.component_class_sink_get_ref - _put_ref = native_bt.component_class_sink_put_ref - _as_component_class_ptr = native_bt.component_class_sink_as_component_class + _get_ref = staticmethod(native_bt.component_class_sink_get_ref) + _put_ref = staticmethod(native_bt.component_class_sink_put_ref) + _as_component_class_ptr = staticmethod(native_bt.component_class_sink_as_component_class) def _handle_component_status(status, gen_error_msg): @@ -209,24 +209,24 @@ class _Component: class _SourceComponent(_Component): - _borrow_component_class_ptr = native_bt.component_source_borrow_class_const + _borrow_component_class_ptr = staticmethod(native_bt.component_source_borrow_class_const) _comp_cls_type = native_bt.COMPONENT_CLASS_TYPE_SOURCE - _as_component_class_ptr = native_bt.component_class_source_as_component_class - _as_component_ptr = native_bt.component_source_as_component_const + _as_component_class_ptr = staticmethod(native_bt.component_class_source_as_component_class) + _as_component_ptr = staticmethod(native_bt.component_source_as_component_const) class _FilterComponent(_Component): - _borrow_component_class_ptr = native_bt.component_filter_borrow_class_const + _borrow_component_class_ptr = staticmethod(native_bt.component_filter_borrow_class_const) _comp_cls_type = native_bt.COMPONENT_CLASS_TYPE_FILTER - _as_component_class_ptr = native_bt.component_class_filter_as_component_class - _as_component_ptr = native_bt.component_filter_as_component_const + _as_component_class_ptr = staticmethod(native_bt.component_class_filter_as_component_class) + _as_component_ptr = staticmethod(native_bt.component_filter_as_component_const) class _SinkComponent(_Component): - _borrow_component_class_ptr = native_bt.component_sink_borrow_class_const + _borrow_component_class_ptr = staticmethod(native_bt.component_sink_borrow_class_const) _comp_cls_type = native_bt.COMPONENT_CLASS_TYPE_SINK - _as_component_class_ptr = native_bt.component_class_sink_as_component_class - _as_component_ptr = native_bt.component_sink_as_component_const + _as_component_class_ptr = staticmethod(native_bt.component_class_sink_as_component_class) + _as_component_ptr = staticmethod(native_bt.component_sink_as_component_const) # This is analogous to _GenericSourceComponentClass, but for source @@ -261,8 +261,8 @@ class _GenericFilterComponent(object._SharedObject, _FilterComponent): # This is analogous to _GenericSinkComponentClass, but for sink # component objects. class _GenericSinkComponent(object._SharedObject, _SinkComponent): - _get_ref = native_bt.component_sink_get_ref - _put_ref = native_bt.component_sink_put_ref + _get_ref = staticmethod(native_bt.component_sink_get_ref) + _put_ref = staticmethod(native_bt.component_sink_put_ref) @property def input_ports(self): @@ -629,7 +629,7 @@ class _UserComponent(metaclass=_UserComponentType): class _UserSourceComponent(_UserComponent, _SourceComponent): - _as_not_self_specific_component_ptr = native_bt.self_component_source_as_component_source + _as_not_self_specific_component_ptr = staticmethod(native_bt.self_component_source_as_component_source) @property def _output_ports(self): @@ -649,7 +649,7 @@ class _UserSourceComponent(_UserComponent, _SourceComponent): class _UserFilterComponent(_UserComponent, _FilterComponent): - _as_not_self_specific_component_ptr = native_bt.self_component_filter_as_component_filter + _as_not_self_specific_component_ptr = staticmethod(native_bt.self_component_filter_as_component_filter) @property def _output_ports(self): @@ -685,7 +685,7 @@ class _UserFilterComponent(_UserComponent, _FilterComponent): class _UserSinkComponent(_UserComponent, _SinkComponent): - _as_not_self_specific_component_ptr = native_bt.self_component_sink_as_component_sink + _as_not_self_specific_component_ptr = staticmethod(native_bt.self_component_sink_as_component_sink) @property def _input_ports(self): diff --git a/bindings/python/bt2/bt2/graph.py b/bindings/python/bt2/bt2/graph.py index e42b2425..f79c954e 100644 --- a/bindings/python/bt2/bt2/graph.py +++ b/bindings/python/bt2/bt2/graph.py @@ -87,8 +87,8 @@ def _graph_ports_disconnected_listener_from_native(user_listener, class Graph(object._SharedObject): - _get_ref = native_bt.graph_get_ref - _put_ref = native_bt.graph_put_ref + _get_ref = staticmethod(native_bt.graph_get_ref) + _put_ref = staticmethod(native_bt.graph_put_ref) def __init__(self): ptr = native_bt.graph_create() diff --git a/bindings/python/bt2/bt2/plugin.py b/bindings/python/bt2/bt2/plugin.py index 39223a8c..2d0d8b05 100644 --- a/bindings/python/bt2/bt2/plugin.py +++ b/bindings/python/bt2/bt2/plugin.py @@ -54,8 +54,8 @@ def find_plugin(name): class _PluginSet(object._SharedObject, collections.abc.Sequence): - _put_ref = native_bt.plugin_set_put_ref - _get_ref = native_bt.plugin_set_get_ref + _put_ref = staticmethod(native_bt.plugin_set_put_ref) + _get_ref = staticmethod(native_bt.plugin_set_get_ref) def __len__(self): count = native_bt.plugin_set_get_plugin_count(self._ptr) @@ -150,29 +150,29 @@ class _PluginComponentClasses(collections.abc.Mapping): class _PluginSourceComponentClasses(_PluginComponentClasses): - _component_class_count = native_bt.plugin_get_source_component_class_count - _borrow_component_class_by_name = native_bt.plugin_borrow_source_component_class_by_name_const - _borrow_component_class_by_index = native_bt.plugin_borrow_source_component_class_by_index_const + _component_class_count = staticmethod(native_bt.plugin_get_source_component_class_count) + _borrow_component_class_by_name = staticmethod(native_bt.plugin_borrow_source_component_class_by_name_const) + _borrow_component_class_by_index = staticmethod(native_bt.plugin_borrow_source_component_class_by_index_const) _comp_cls_type = native_bt.COMPONENT_CLASS_TYPE_SOURCE class _PluginFilterComponentClasses(_PluginComponentClasses): - _component_class_count = native_bt.plugin_get_filter_component_class_count - _borrow_component_class_by_name = native_bt.plugin_borrow_filter_component_class_by_name_const - _borrow_component_class_by_index = native_bt.plugin_borrow_filter_component_class_by_index_const + _component_class_count = staticmethod(native_bt.plugin_get_filter_component_class_count) + _borrow_component_class_by_name = staticmethod(native_bt.plugin_borrow_filter_component_class_by_name_const) + _borrow_component_class_by_index = staticmethod(native_bt.plugin_borrow_filter_component_class_by_index_const) _comp_cls_type = native_bt.COMPONENT_CLASS_TYPE_FILTER class _PluginSinkComponentClasses(_PluginComponentClasses): - _component_class_count = native_bt.plugin_get_sink_component_class_count - _borrow_component_class_by_name = native_bt.plugin_borrow_sink_component_class_by_name_const - _borrow_component_class_by_index = native_bt.plugin_borrow_sink_component_class_by_index_const + _component_class_count = staticmethod(native_bt.plugin_get_sink_component_class_count) + _borrow_component_class_by_name = staticmethod(native_bt.plugin_borrow_sink_component_class_by_name_const) + _borrow_component_class_by_index = staticmethod(native_bt.plugin_borrow_sink_component_class_by_index_const) _comp_cls_type = native_bt.COMPONENT_CLASS_TYPE_SINK class _Plugin(object._SharedObject): - _put_ref = native_bt.plugin_put_ref - _get_ref = native_bt.plugin_get_ref + _put_ref = staticmethod(native_bt.plugin_put_ref) + _get_ref = staticmethod(native_bt.plugin_get_ref) @property def name(self): diff --git a/bindings/python/bt2/bt2/query_executor.py b/bindings/python/bt2/bt2/query_executor.py index ce31f694..a87713ff 100644 --- a/bindings/python/bt2/bt2/query_executor.py +++ b/bindings/python/bt2/bt2/query_executor.py @@ -26,8 +26,8 @@ import bt2 class QueryExecutor(object._SharedObject): - _get_ref = native_bt.query_executor_get_ref - _put_ref = native_bt.query_executor_put_ref + _get_ref = staticmethod(native_bt.query_executor_get_ref) + _put_ref = staticmethod(native_bt.query_executor_put_ref) def _handle_status(self, status, gen_error_msg): if status == native_bt.QUERY_EXECUTOR_STATUS_AGAIN: diff --git a/bindings/python/bt2/bt2/value.py b/bindings/python/bt2/bt2/value.py index 5beccbcd..d8b8332e 100644 --- a/bindings/python/bt2/bt2/value.py +++ b/bindings/python/bt2/bt2/value.py @@ -86,8 +86,8 @@ def create_value(value): class _Value(object._SharedObject, metaclass=abc.ABCMeta): - _get_ref = native_bt.value_get_ref - _put_ref = native_bt.value_put_ref + _get_ref = staticmethod(native_bt.value_get_ref) + _put_ref = staticmethod(native_bt.value_put_ref) def __eq__(self, other): if other is None: @@ -396,18 +396,18 @@ class _IntegerValue(_IntegralValue): class UnsignedIntegerValue(_IntegerValue): _check_int_range = staticmethod(utils._check_uint64) - _create_default_value = native_bt.value_unsigned_integer_create - _create_value = native_bt.value_unsigned_integer_create_init - _set_value = native_bt.value_unsigned_integer_set - _get_value = native_bt.value_unsigned_integer_get + _create_default_value = staticmethod(native_bt.value_unsigned_integer_create) + _create_value = staticmethod(native_bt.value_unsigned_integer_create_init) + _set_value = staticmethod(native_bt.value_unsigned_integer_set) + _get_value = staticmethod(native_bt.value_unsigned_integer_get) class SignedIntegerValue(_IntegerValue): _check_int_range = staticmethod(utils._check_int64) - _create_default_value = native_bt.value_signed_integer_create - _create_value = native_bt.value_signed_integer_create_init - _set_value = native_bt.value_signed_integer_set - _get_value = native_bt.value_signed_integer_get + _create_default_value = staticmethod(native_bt.value_signed_integer_create) + _create_value = staticmethod(native_bt.value_signed_integer_create_init) + _set_value = staticmethod(native_bt.value_signed_integer_set) + _get_value = staticmethod(native_bt.value_signed_integer_get) class RealValue(_RealValue): -- 2.34.1