bt2: add option field class and field support
[babeltrace.git] / src / bindings / python / bt2 / bt2 / field.py
index bb35300c72ac5222c4e00cb39330e3c7610298cb..f674a465d5d773a4770d5037a77f8fcccc5dc108 100644 (file)
 # THE SOFTWARE.
 
 from bt2 import native_bt, object, utils
-import bt2.field_class
+from bt2 import field_class as bt2_field_class
 import collections.abc
 import functools
 import numbers
 import math
-import bt2
 
 
 def _create_field_from_ptr(ptr, owner_ptr, owner_get_ref, owner_put_ref):
     field_class_ptr = native_bt.field_borrow_class_const(ptr)
-    utils._handle_ptr(field_class_ptr, "cannot get field object's class")
     typeid = native_bt.field_class_get_type(field_class_ptr)
     field = _TYPE_ID_TO_OBJ[typeid]._create_from_ptr_and_get_ref(
         ptr, owner_ptr, owner_get_ref, owner_put_ref
@@ -39,16 +37,20 @@ def _create_field_from_ptr(ptr, owner_ptr, owner_get_ref, owner_put_ref):
     return field
 
 
-# Get the "effective" field of `field`.  If `field` is a variant, return the
-# currently selected field.  If `field` is of any other type, return `field`
+# Get the "effective" field of `field`.  If `field` is a variant, return
+# the currently selected field.  If `field` is an option, return the
+# content field.  If `field` is of any other type, return `field`
 # directly.
 
 
 def _get_leaf_field(field):
-    if not isinstance(field, _VariantField):
-        return field
+    if isinstance(field, _VariantField):
+        return _get_leaf_field(field.selected_option)
 
-    return _get_leaf_field(field.selected_option)
+    if isinstance(field, _OptionField):
+        return _get_leaf_field(field.field)
+
+    return field
 
 
 class _Field(object._UniqueObject):
@@ -60,7 +62,7 @@ class _Field(object._UniqueObject):
     def field_class(self):
         field_class_ptr = native_bt.field_borrow_class_const(self._ptr)
         assert field_class_ptr is not None
-        return bt2.field_class._create_field_class_from_ptr_and_get_ref(field_class_ptr)
+        return bt2_field_class._create_field_class_from_ptr_and_get_ref(field_class_ptr)
 
     def _repr(self):
         raise NotImplementedError
@@ -73,8 +75,8 @@ class _Field(object._UniqueObject):
 class _NumericField(_Field):
     @staticmethod
     def _extract_value(other):
-        if isinstance(other, bool):
-            return other
+        if isinstance(other, _BoolField) or isinstance(other, bool):
+            return bool(other)
 
         if isinstance(other, numbers.Integral):
             return int(other)
@@ -210,6 +212,36 @@ class _IntegralField(_NumericField, numbers.Integral):
         return ~self._value
 
 
+class _BoolField(_IntegralField, _Field):
+    _NAME = 'Boolean'
+
+    def __bool__(self):
+        return self._value
+
+    def _value_to_bool(self, value):
+        if isinstance(value, _BoolField):
+            value = value._value
+
+        if not isinstance(value, bool):
+            raise TypeError(
+                "'{}' object is not a 'bool' or '_BoolField' object".format(
+                    value.__class__
+                )
+            )
+
+        return value
+
+    @property
+    def _value(self):
+        return bool(native_bt.field_bool_get_value(self._ptr))
+
+    def _set_value(self, value):
+        value = self._value_to_bool(value)
+        native_bt.field_bool_set_value(self._ptr, value)
+
+    value = property(fset=_set_value)
+
+
 class _IntegerField(_IntegralField, _Field):
     pass
 
@@ -228,11 +260,11 @@ class _UnsignedIntegerField(_IntegerField, _Field):
 
     @property
     def _value(self):
-        return native_bt.field_unsigned_integer_get_value(self._ptr)
+        return native_bt.field_integer_unsigned_get_value(self._ptr)
 
     def _set_value(self, value):
         value = self._value_to_int(value)
-        native_bt.field_unsigned_integer_set_value(self._ptr, value)
+        native_bt.field_integer_unsigned_set_value(self._ptr, value)
 
     value = property(fset=_set_value)
 
@@ -251,11 +283,11 @@ class _SignedIntegerField(_IntegerField, _Field):
 
     @property
     def _value(self):
-        return native_bt.field_signed_integer_get_value(self._ptr)
+        return native_bt.field_integer_signed_get_value(self._ptr)
 
     def _set_value(self, value):
         value = self._value_to_int(value)
-        native_bt.field_signed_integer_set_value(self._ptr, value)
+        native_bt.field_integer_signed_set_value(self._ptr, value)
 
     value = property(fset=_set_value)
 
@@ -296,14 +328,14 @@ class _EnumerationField(_IntegerField):
 class _UnsignedEnumerationField(_EnumerationField, _UnsignedIntegerField):
     _NAME = 'Unsigned Enumeration'
     _get_mapping_labels = staticmethod(
-        native_bt.field_unsigned_enumeration_get_mapping_labels
+        native_bt.field_enumeration_unsigned_get_mapping_labels
     )
 
 
 class _SignedEnumerationField(_EnumerationField, _SignedIntegerField):
     _NAME = 'Signed Enumeration'
     _get_mapping_labels = staticmethod(
-        native_bt.field_signed_enumeration_get_mapping_labels
+        native_bt.field_enumeration_signed_get_mapping_labels
     )
 
 
@@ -452,6 +484,50 @@ class _StructureField(_ContainerField, collections.abc.MutableMapping):
         )
 
 
+class _OptionField(_Field):
+    _NAME = 'Option'
+
+    @property
+    def field(self):
+        field_ptr = native_bt.field_option_borrow_field_const(self._ptr)
+
+        if field_ptr is None:
+            return
+
+        return _create_field_from_ptr(
+            field_ptr, self._owner_ptr, self._owner_get_ref, self._owner_put_ref
+        )
+
+    @property
+    def has_field(self):
+        return self.field is not None
+
+    @has_field.setter
+    def has_field(self, value):
+        utils._check_bool(value)
+        native_bt.field_option_set_has_field(self._ptr, value)
+
+    def _spec_eq(self, other):
+        return _get_leaf_field(self) == other
+
+    def __bool__(self):
+        return self.has_field
+
+    def __str__(self):
+        return str(self.field)
+
+    def _repr(self):
+        return repr(self.field)
+
+    def _set_value(self, value):
+        self.has_field = True
+        field = self.field
+        assert field is not None
+        field.value = value
+
+    value = property(fset=_set_value)
+
+
 class _VariantField(_ContainerField, _Field):
     _NAME = 'Variant'
 
@@ -465,8 +541,10 @@ class _VariantField(_ContainerField, _Field):
 
     @property
     def selected_option(self):
+        # TODO: Is there a way to check if the variant field has a selected_option,
+        # so we can raise an exception instead of hitting a pre-condition check?
+        # If there is something, that check should be added to selected_option_index too.
         field_ptr = native_bt.field_variant_borrow_selected_option_field(self._ptr)
-        utils._handle_ptr(field_ptr, "cannot get variant field's selected option")
 
         return _create_field_from_ptr(
             field_ptr, self._owner_ptr, self._owner_get_ref, self._owner_put_ref
@@ -574,7 +652,7 @@ class _DynamicArrayField(_ArrayField, _Field):
 
     def _set_length(self, length):
         utils._check_uint64(length)
-        status = native_bt.field_dynamic_array_set_length(self._ptr, length)
+        status = native_bt.field_array_dynamic_set_length(self._ptr, length)
         utils._handle_func_status(status, "cannot set dynamic array length")
 
     length = property(fget=_ArrayField._get_length, fset=_set_length)
@@ -591,6 +669,7 @@ class _DynamicArrayField(_ArrayField, _Field):
 
 
 _TYPE_ID_TO_OBJ = {
+    native_bt.FIELD_CLASS_TYPE_BOOL: _BoolField,
     native_bt.FIELD_CLASS_TYPE_UNSIGNED_INTEGER: _UnsignedIntegerField,
     native_bt.FIELD_CLASS_TYPE_SIGNED_INTEGER: _SignedIntegerField,
     native_bt.FIELD_CLASS_TYPE_REAL: _RealField,
@@ -600,6 +679,7 @@ _TYPE_ID_TO_OBJ = {
     native_bt.FIELD_CLASS_TYPE_STRUCTURE: _StructureField,
     native_bt.FIELD_CLASS_TYPE_STATIC_ARRAY: _StaticArrayField,
     native_bt.FIELD_CLASS_TYPE_DYNAMIC_ARRAY: _DynamicArrayField,
+    native_bt.FIELD_CLASS_TYPE_OPTION: _OptionField,
     native_bt.FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR: _VariantField,
     native_bt.FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR: _VariantField,
     native_bt.FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR: _VariantField,
This page took 0.027436 seconds and 4 git commands to generate.