From 278239516fde3ce2af2214922917f08abd451880 Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Mon, 21 Oct 2024 14:20:01 -0400 Subject: [PATCH] Fix: bt2: correctly handle empty result of bt_field_enumeration_unsigned_get_mapping_labels When calling `_EnumerationFieldClassConst.mappings_for_value()` and the result is empty (no matching mappings), we get: File "/home/smarchi/build/babeltrace/src/bindings/python/bt2/build/build_lib/bt2/field_class.py", line 240, in mappings_for_value return [self[label] for label in labels] ^^^^^^ TypeError: 'NoneType' object is not iterable Here's what happens: - When the input value matches no mappings, the library sets the array output parameter to `NULL`. - The SWIG argout typemap checks the array output parameter value to choose between returning a list or `None`. So in this case, we return the tuple `(__BT_FUNC_STATUS_OK, None)`. - Back in the Python side, we try to iterate over `None`. Fix this by checking the status in the typemap to see if the call succeeded. Add a corresponding test. Change-Id: If1c7de435c27b9c37b67b66a7b8384480ac654e1 Signed-off-by: Simon Marchi Reviewed-on: https://review.lttng.org/c/babeltrace/+/13385 Reviewed-by: Philippe Proulx --- src/bindings/python/bt2/bt2/native_bt_field_class.i | 2 +- tests/bindings/python/bt2/test_field_class.py | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/bindings/python/bt2/bt2/native_bt_field_class.i b/src/bindings/python/bt2/bt2/native_bt_field_class.i index 72aaa9ca..cfcd2234 100644 --- a/src/bindings/python/bt2/bt2/native_bt_field_class.i +++ b/src/bindings/python/bt2/bt2/native_bt_field_class.i @@ -14,7 +14,7 @@ %typemap(argout) (bt_field_class_enumeration_mapping_label_array *labels, uint64_t *count) { - if (*$1) { + if (result == __BT_FUNC_STATUS_OK) { PyObject *py_label_list = PyList_New(*$2); uint64_t i; diff --git a/tests/bindings/python/bt2/test_field_class.py b/tests/bindings/python/bt2/test_field_class.py index cb011a6e..c000424f 100644 --- a/tests/bindings/python/bt2/test_field_class.py +++ b/tests/bindings/python/bt2/test_field_class.py @@ -388,6 +388,11 @@ class _EnumerationFieldClassTestCase(_TestIntegerFieldClassProps): expected_labels = set(["a", "c"]) self.assertEqual(labels, expected_labels) + def test_find_by_value_none_found(self): + self._fc.add_mapping("a", self._ranges1) + mappings = self._fc.mappings_for_value(999999) + self.assertEqual(mappings, []) + class UnsignedEnumerationFieldClassTestCase( _EnumerationFieldClassTestCase, _TestFieldClass, unittest.TestCase -- 2.34.1