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 <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>
This page took 0.025498 seconds and 4 git commands to generate.