bt2: always use staticmethod() with native function class attributes
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Fri, 31 May 2019 11:56:44 +0000 (07:56 -0400)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Fri, 31 May 2019 14:19:24 +0000 (10:19 -0400)
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 <eeppeliteloop@gmail.com>
Change-Id: Ic51397e34132adc78fddc3105878080a8bf74ff9
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1357
Tested-by: jenkins
Reviewed-by: Simon Marchi <simon.marchi@efficios.com>
bindings/python/bt2/bt2/component.py
bindings/python/bt2/bt2/graph.py
bindings/python/bt2/bt2/plugin.py
bindings/python/bt2/bt2/query_executor.py
bindings/python/bt2/bt2/value.py

index 8e07da3267edf17648d4fc658a4b8f71cdc8e740..3c820cba0b63f61fa2dda32e4f0a6b9ecd06bbfa 100644 (file)
@@ -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):
index e42b242568e4e2215a5976bb09636e7ba00587ff..f79c954e1b59d252839a5ba2df78ec7e0a5b0bc8 100644 (file)
@@ -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()
index 39223a8ce6f255b9878fe2bbec3cf4c6ba5ded0a..2d0d8b057303afa44d1e8cb0a832ac429c4b11c3 100644 (file)
@@ -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):
index ce31f694ec73cb83064a0780833ab58bed0d8a38..a87713ff1c8a4f2c540fb35fabd81592cd910692 100644 (file)
@@ -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:
index 5beccbcd197689666c8485c869f48470a85acd7f..d8b8332eecd87bd06942ac3a839b0a96c42b5eeb 100644 (file)
@@ -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):
This page took 0.029896 seconds and 4 git commands to generate.