bt2: rename `_Field.field_class` -> `_Field.cls`
[babeltrace.git] / src / bindings / python / bt2 / bt2 / field.py
index 0f3e5e7ee32eb11b797f370723f52de5145ca098..ecbd9715753ce3e6fcec9d4f36dff19f288abd32 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)
+        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)
+
+    if isinstance(field, _OptionField):
+        return _get_leaf_field(field.field)
 
-    return _get_leaf_field(field.selected_option)
+    return field
 
 
 class _Field(object._UniqueObject):
@@ -55,10 +59,10 @@ class _Field(object._UniqueObject):
         return self._spec_eq(other)
 
     @property
-    def field_class(self):
+    def cls(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
@@ -67,12 +71,40 @@ class _Field(object._UniqueObject):
         return self._repr()
 
 
+class _BitArrayField(_Field):
+    _NAME = 'Bit array'
+
+    @property
+    def value_as_integer(self):
+        return native_bt.field_bit_array_get_value_as_integer(self._ptr)
+
+    @value_as_integer.setter
+    def value_as_integer(self, value):
+        utils._check_uint64(value)
+        native_bt.field_bit_array_set_value_as_integer(self._ptr, value)
+
+    def _spec_eq(self, other):
+        if type(other) is not type(self):
+            return False
+
+        return self.value_as_integer == other.value_as_integer
+
+    def _repr(self):
+        return repr(self.value_as_integer)
+
+    def __str__(self):
+        return str(self.value_as_integer)
+
+    def __len__(self):
+        return self.cls.length
+
+
 @functools.total_ordering
 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)
@@ -83,7 +115,9 @@ class _NumericField(_Field):
         if isinstance(other, numbers.Complex):
             return complex(other)
 
-        raise TypeError("'{}' object is not a number object".format(other.__class__.__name__))
+        raise TypeError(
+            "'{}' object is not a number object".format(other.__class__.__name__)
+        )
 
     def __int__(self):
         return int(self._value)
@@ -96,8 +130,11 @@ class _NumericField(_Field):
 
     def __lt__(self, other):
         if not isinstance(other, numbers.Number):
-            raise TypeError('unorderable types: {}() < {}()'.format(self.__class__.__name__,
-                                                                    other.__class__.__name__))
+            raise TypeError(
+                'unorderable types: {}() < {}()'.format(
+                    self.__class__.__name__, other.__class__.__name__
+                )
+            )
 
         return self._value < self._extract_value(other)
 
@@ -203,6 +240,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
 
@@ -221,11 +288,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)
 
@@ -244,11 +311,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)
 
@@ -280,8 +347,7 @@ class _EnumerationField(_IntegerField):
     @property
     def labels(self):
         status, labels = self._get_mapping_labels(self._ptr)
-        utils._handle_func_status(status,
-                                  "cannot get label for enumeration field")
+        utils._handle_func_status(status, "cannot get label for enumeration field")
 
         assert labels is not None
         return labels
@@ -289,12 +355,16 @@ class _EnumerationField(_IntegerField):
 
 class _UnsignedEnumerationField(_EnumerationField, _UnsignedIntegerField):
     _NAME = 'Unsigned Enumeration'
-    _get_mapping_labels = staticmethod(native_bt.field_unsigned_enumeration_get_mapping_labels)
+    _get_mapping_labels = staticmethod(
+        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)
+    _get_mapping_labels = staticmethod(
+        native_bt.field_enumeration_signed_get_mapping_labels
+    )
 
 
 @functools.total_ordering
@@ -347,8 +417,9 @@ class _StringField(_Field):
     def __iadd__(self, value):
         value = self._value_to_str(value)
         status = native_bt.field_string_append(self._ptr, value)
-        utils._handle_func_status(status,
-                                  "cannot append to string field object's value")
+        utils._handle_func_status(
+            status, "cannot append to string field object's value"
+        )
         return self
 
 
@@ -369,7 +440,7 @@ class _StructureField(_ContainerField, collections.abc.MutableMapping):
     _NAME = 'Structure'
 
     def _count(self):
-        return len(self.field_class)
+        return len(self.cls)
 
     def __setitem__(self, key, value):
         # raises if key is somehow invalid
@@ -381,7 +452,7 @@ class _StructureField(_ContainerField, collections.abc.MutableMapping):
 
     def __iter__(self):
         # same name iterator
-        return iter(self.field_class)
+        return iter(self.cls)
 
     def _spec_eq(self, other):
         if not isinstance(other, collections.abc.Mapping):
@@ -415,14 +486,16 @@ class _StructureField(_ContainerField, collections.abc.MutableMapping):
 
     def __getitem__(self, key):
         utils._check_str(key)
-        field_ptr = native_bt.field_structure_borrow_member_field_by_name(self._ptr, key)
+        field_ptr = native_bt.field_structure_borrow_member_field_by_name(
+            self._ptr, key
+        )
 
         if field_ptr is None:
             raise KeyError(key)
 
-        return _create_field_from_ptr(field_ptr, self._owner_ptr,
-                                      self._owner_get_ref,
-                                      self._owner_put_ref)
+        return _create_field_from_ptr(
+            field_ptr, self._owner_ptr, self._owner_get_ref, self._owner_put_ref
+        )
 
     def member_at_index(self, index):
         utils._check_uint64(index)
@@ -430,11 +503,57 @@ class _StructureField(_ContainerField, collections.abc.MutableMapping):
         if index >= len(self):
             raise IndexError
 
-        field_ptr = native_bt.field_structure_borrow_member_field_by_index(self._ptr, index)
+        field_ptr = native_bt.field_structure_borrow_member_field_by_index(
+            self._ptr, index
+        )
         assert field_ptr is not None
-        return _create_field_from_ptr(field_ptr, self._owner_ptr,
-                                      self._owner_get_ref,
-                                      self._owner_put_ref)
+        return _create_field_from_ptr(
+            field_ptr, self._owner_ptr, self._owner_get_ref, self._owner_put_ref
+        )
+
+
+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):
@@ -446,16 +565,18 @@ class _VariantField(_ContainerField, _Field):
 
     @selected_option_index.setter
     def selected_option_index(self, index):
-        native_bt.field_variant_select_option_field(self._ptr, index)
+        native_bt.field_variant_select_option_field_by_index(self._ptr, index)
 
     @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)
+        return _create_field_from_ptr(
+            field_ptr, self._owner_ptr, self._owner_get_ref, self._owner_put_ref
+        )
 
     def _spec_eq(self, other):
         return _get_leaf_field(self) == other
@@ -483,18 +604,24 @@ class _ArrayField(_ContainerField, _Field, collections.abc.MutableSequence):
 
     def __getitem__(self, index):
         if not isinstance(index, numbers.Integral):
-            raise TypeError("'{}' is not an integral number object: invalid index".format(index.__class__.__name__))
+            raise TypeError(
+                "'{}' is not an integral number object: invalid index".format(
+                    index.__class__.__name__
+                )
+            )
 
         index = int(index)
 
         if index < 0 or index >= len(self):
             raise IndexError('{} field object index is out of range'.format(self._NAME))
 
-        field_ptr = native_bt.field_array_borrow_element_field_by_index(self._ptr, index)
-        assert(field_ptr)
-        return _create_field_from_ptr(field_ptr, self._owner_ptr,
-                                      self._owner_get_ref,
-                                      self._owner_put_ref)
+        field_ptr = native_bt.field_array_borrow_element_field_by_index(
+            self._ptr, index
+        )
+        assert field_ptr
+        return _create_field_from_ptr(
+            field_ptr, self._owner_ptr, self._owner_get_ref, self._owner_put_ref
+        )
 
     def __setitem__(self, index, value):
         # raises if index is somehow invalid
@@ -536,8 +663,7 @@ class _StaticArrayField(_ArrayField, _Field):
 
     def _set_value(self, values):
         if len(self) != len(values):
-            raise ValueError(
-                'expected length of value and array field to match')
+            raise ValueError('expected length of value and array field to match')
 
         for index, value in enumerate(values):
             if value is not None:
@@ -554,7 +680,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)
@@ -571,6 +697,8 @@ class _DynamicArrayField(_ArrayField, _Field):
 
 
 _TYPE_ID_TO_OBJ = {
+    native_bt.FIELD_CLASS_TYPE_BOOL: _BoolField,
+    native_bt.FIELD_CLASS_TYPE_BIT_ARRAY: _BitArrayField,
     native_bt.FIELD_CLASS_TYPE_UNSIGNED_INTEGER: _UnsignedIntegerField,
     native_bt.FIELD_CLASS_TYPE_SIGNED_INTEGER: _SignedIntegerField,
     native_bt.FIELD_CLASS_TYPE_REAL: _RealField,
@@ -580,5 +708,8 @@ _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_VARIANT: _VariantField,
+    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.037731 seconds and 4 git commands to generate.